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

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [i386/] [i386.md] - Blame information for rev 38

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

Line No. Rev Author Line
1 38 julius
;; 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
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
;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
30
;; constraint letters.
31
;;
32
;; The special asm out single letter directives following a '%' are:
33
;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
34
;;     operands[1].
35
;; 'L' Print the opcode suffix for a 32-bit integer opcode.
36
;; 'W' Print the opcode suffix for a 16-bit integer opcode.
37
;; 'B' Print the opcode suffix for an 8-bit integer opcode.
38
;; 'Q' Print the opcode suffix for a 64-bit float opcode.
39
;; 'S' Print the opcode suffix for a 32-bit float opcode.
40
;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
41
;; 'J' Print the appropriate jump operand.
42
;;
43
;; 'b' Print the QImode name of the register for the indicated operand.
44
;;     %b0 would print %al if operands[0] is reg 0.
45
;; 'w' Likewise, print the HImode name of the register.
46
;; 'k' Likewise, print the SImode name of the register.
47
;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
48
;; 'y' Print "st(0)" instead of "st" as a register.
49
 
50
;; UNSPEC usage:
51
 
52
(define_constants
53
  [; Relocation specifiers
54
   (UNSPEC_GOT                  0)
55
   (UNSPEC_GOTOFF               1)
56
   (UNSPEC_GOTPCREL             2)
57
   (UNSPEC_GOTTPOFF             3)
58
   (UNSPEC_TPOFF                4)
59
   (UNSPEC_NTPOFF               5)
60
   (UNSPEC_DTPOFF               6)
61
   (UNSPEC_GOTNTPOFF            7)
62
   (UNSPEC_INDNTPOFF            8)
63
 
64
   ; Prologue support
65
   (UNSPEC_STACK_ALLOC          11)
66
   (UNSPEC_SET_GOT              12)
67
   (UNSPEC_SSE_PROLOGUE_SAVE    13)
68
   (UNSPEC_REG_SAVE             14)
69
   (UNSPEC_DEF_CFA              15)
70
 
71
   ; TLS support
72
   (UNSPEC_TP                   16)
73
   (UNSPEC_TLS_GD               17)
74
   (UNSPEC_TLS_LD_BASE          18)
75
   (UNSPEC_TLSDESC              19)
76
 
77
   ; Other random patterns
78
   (UNSPEC_SCAS                 20)
79
   (UNSPEC_FNSTSW               21)
80
   (UNSPEC_SAHF                 22)
81
   (UNSPEC_FSTCW                23)
82
   (UNSPEC_ADD_CARRY            24)
83
   (UNSPEC_FLDCW                25)
84
   (UNSPEC_REP                  26)
85
   (UNSPEC_EH_RETURN            27)
86
   (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
87
 
88
   ; For SSE/MMX support:
89
   (UNSPEC_FIX_NOTRUNC          30)
90
   (UNSPEC_MASKMOV              31)
91
   (UNSPEC_MOVMSK               32)
92
   (UNSPEC_MOVNT                33)
93
   (UNSPEC_MOVU                 34)
94
   (UNSPEC_RCP                  35)
95
   (UNSPEC_RSQRT                36)
96
   (UNSPEC_SFENCE               37)
97
   (UNSPEC_NOP                  38)     ; prevents combiner cleverness
98
   (UNSPEC_PFRCP                39)
99
   (UNSPEC_PFRCPIT1             40)
100
   (UNSPEC_PFRCPIT2             41)
101
   (UNSPEC_PFRSQRT              42)
102
   (UNSPEC_PFRSQIT1             43)
103
   (UNSPEC_MFENCE               44)
104
   (UNSPEC_LFENCE               45)
105
   (UNSPEC_PSADBW               46)
106
   (UNSPEC_LDQQU                47)
107
 
108
   ; Generic math support
109
   (UNSPEC_COPYSIGN             50)
110
   (UNSPEC_IEEE_MIN             51)     ; not commutative
111
   (UNSPEC_IEEE_MAX             52)     ; not commutative
112
 
113
   ; x87 Floating point
114
   (UNSPEC_SIN                  60)
115
   (UNSPEC_COS                  61)
116
   (UNSPEC_FPATAN               62)
117
   (UNSPEC_FYL2X                63)
118
   (UNSPEC_FYL2XP1              64)
119
   (UNSPEC_FRNDINT              65)
120
   (UNSPEC_FIST                 66)
121
   (UNSPEC_F2XM1                67)
122
 
123
   ; x87 Rounding
124
   (UNSPEC_FRNDINT_FLOOR        70)
125
   (UNSPEC_FRNDINT_CEIL         71)
126
   (UNSPEC_FRNDINT_TRUNC        72)
127
   (UNSPEC_FRNDINT_MASK_PM      73)
128
   (UNSPEC_FIST_FLOOR           74)
129
   (UNSPEC_FIST_CEIL            75)
130
 
131
   ; x87 Double output FP
132
   (UNSPEC_SINCOS_COS           80)
133
   (UNSPEC_SINCOS_SIN           81)
134
   (UNSPEC_TAN_ONE              82)
135
   (UNSPEC_TAN_TAN              83)
136
   (UNSPEC_XTRACT_FRACT         84)
137
   (UNSPEC_XTRACT_EXP           85)
138
   (UNSPEC_FSCALE_FRACT         86)
139
   (UNSPEC_FSCALE_EXP           87)
140
   (UNSPEC_FPREM_F              88)
141
   (UNSPEC_FPREM_U              89)
142
   (UNSPEC_FPREM1_F             90)
143
   (UNSPEC_FPREM1_U             91)
144
 
145
   ; SSP patterns
146
   (UNSPEC_SP_SET               100)
147
   (UNSPEC_SP_TEST              101)
148
   (UNSPEC_SP_TLS_SET           102)
149
   (UNSPEC_SP_TLS_TEST          103)
150
  ])
151
 
152
(define_constants
153
  [(UNSPECV_BLOCKAGE            0)
154
   (UNSPECV_STACK_PROBE         1)
155
   (UNSPECV_EMMS                2)
156
   (UNSPECV_LDMXCSR             3)
157
   (UNSPECV_STMXCSR             4)
158
   (UNSPECV_FEMMS               5)
159
   (UNSPECV_CLFLUSH             6)
160
   (UNSPECV_ALIGN               7)
161
   (UNSPECV_MONITOR             8)
162
   (UNSPECV_MWAIT               9)
163
   (UNSPECV_CMPXCHG_1           10)
164
   (UNSPECV_CMPXCHG_2           11)
165
   (UNSPECV_XCHG                12)
166
   (UNSPECV_LOCK                13)
167
  ])
168
 
169
;; Registers by name.
170
(define_constants
171
  [(BP_REG                       6)
172
   (SP_REG                       7)
173
   (FLAGS_REG                   17)
174
   (FPSR_REG                    18)
175
   (DIRFLAG_REG                 19)
176
  ])
177
 
178
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
179
;; from i386.c.
180
 
181
;; In C guard expressions, put expressions which may be compile-time
182
;; constants first.  This allows for better optimization.  For
183
;; example, write "TARGET_64BIT && reload_completed", not
184
;; "reload_completed && TARGET_64BIT".
185
 
186
 
187
;; Processor type.  This attribute must exactly match the processor_type
188
;; enumeration in i386.h.
189
(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
190
  (const (symbol_ref "ix86_tune")))
191
 
192
;; A basic instruction type.  Refinements due to arguments to be
193
;; provided in other attributes.
194
(define_attr "type"
195
  "other,multi,
196
   alu,alu1,negnot,imov,imovx,lea,
197
   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
198
   icmp,test,ibr,setcc,icmov,
199
   push,pop,call,callv,leave,
200
   str,cld,
201
   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
202
   sselog,sselog1,sseiadd,sseishft,sseimul,
203
   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
204
   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
205
  (const_string "other"))
206
 
207
;; Main data type used by the insn
208
(define_attr "mode"
209
  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
210
  (const_string "unknown"))
211
 
212
;; The CPU unit operations uses.
213
(define_attr "unit" "integer,i387,sse,mmx,unknown"
214
  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
215
           (const_string "i387")
216
         (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
217
                          sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218
           (const_string "sse")
219
         (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220
           (const_string "mmx")
221
         (eq_attr "type" "other")
222
           (const_string "unknown")]
223
         (const_string "integer")))
224
 
225
;; The (bounding maximum) length of an instruction immediate.
226
(define_attr "length_immediate" ""
227
  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228
           (const_int 0)
229
         (eq_attr "unit" "i387,sse,mmx")
230
           (const_int 0)
231
         (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232
                          imul,icmp,push,pop")
233
           (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
234
         (eq_attr "type" "imov,test")
235
           (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
236
         (eq_attr "type" "call")
237
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
238
             (const_int 4)
239
             (const_int 0))
240
         (eq_attr "type" "callv")
241
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
242
             (const_int 4)
243
             (const_int 0))
244
         ;; We don't know the size before shorten_branches.  Expect
245
         ;; the instruction to fit for better scheduling.
246
         (eq_attr "type" "ibr")
247
           (const_int 1)
248
         ]
249
         (symbol_ref "/* Update immediate_length and other attributes! */
250
                      gcc_unreachable (),1")))
251
 
252
;; The (bounding maximum) length of an instruction address.
253
(define_attr "length_address" ""
254
  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255
           (const_int 0)
256
         (and (eq_attr "type" "call")
257
              (match_operand 0 "constant_call_address_operand" ""))
258
             (const_int 0)
259
         (and (eq_attr "type" "callv")
260
              (match_operand 1 "constant_call_address_operand" ""))
261
             (const_int 0)
262
         ]
263
         (symbol_ref "ix86_attr_length_address_default (insn)")))
264
 
265
;; Set when length prefix is used.
266
(define_attr "prefix_data16" ""
267
  (if_then_else (ior (eq_attr "mode" "HI")
268
                     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
269
    (const_int 1)
270
    (const_int 0)))
271
 
272
;; Set when string REP prefix is used.
273
(define_attr "prefix_rep" ""
274
  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
275
    (const_int 1)
276
    (const_int 0)))
277
 
278
;; Set when 0f opcode prefix is used.
279
(define_attr "prefix_0f" ""
280
  (if_then_else
281
    (ior (eq_attr "type" "imovx,setcc,icmov")
282
         (eq_attr "unit" "sse,mmx"))
283
    (const_int 1)
284
    (const_int 0)))
285
 
286
;; Set when REX opcode prefix is used.
287
(define_attr "prefix_rex" ""
288
  (cond [(and (eq_attr "mode" "DI")
289
              (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290
           (const_int 1)
291
         (and (eq_attr "mode" "QI")
292
              (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
293
                  (const_int 0)))
294
           (const_int 1)
295
         (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
296
             (const_int 0))
297
           (const_int 1)
298
        ]
299
        (const_int 0)))
300
 
301
;; Set when modrm byte is used.
302
(define_attr "modrm" ""
303
  (cond [(eq_attr "type" "str,cld,leave")
304
           (const_int 0)
305
         (eq_attr "unit" "i387")
306
           (const_int 0)
307
         (and (eq_attr "type" "incdec")
308
              (ior (match_operand:SI 1 "register_operand" "")
309
                   (match_operand:HI 1 "register_operand" "")))
310
           (const_int 0)
311
         (and (eq_attr "type" "push")
312
              (not (match_operand 1 "memory_operand" "")))
313
           (const_int 0)
314
         (and (eq_attr "type" "pop")
315
              (not (match_operand 0 "memory_operand" "")))
316
           (const_int 0)
317
         (and (eq_attr "type" "imov")
318
              (ior (and (match_operand 0 "register_operand" "")
319
                        (match_operand 1 "immediate_operand" ""))
320
                   (ior (and (match_operand 0 "ax_reg_operand" "")
321
                             (match_operand 1 "memory_displacement_only_operand" ""))
322
                        (and (match_operand 0 "memory_displacement_only_operand" "")
323
                             (match_operand 1 "ax_reg_operand" "")))))
324
           (const_int 0)
325
         (and (eq_attr "type" "call")
326
              (match_operand 0 "constant_call_address_operand" ""))
327
             (const_int 0)
328
         (and (eq_attr "type" "callv")
329
              (match_operand 1 "constant_call_address_operand" ""))
330
             (const_int 0)
331
         ]
332
         (const_int 1)))
333
 
334
;; The (bounding maximum) length of an instruction in bytes.
335
;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
336
;; Later we may want to split them and compute proper length as for
337
;; other insns.
338
(define_attr "length" ""
339
  (cond [(eq_attr "type" "other,multi,fistp,frndint")
340
           (const_int 16)
341
         (eq_attr "type" "fcmp")
342
           (const_int 4)
343
         (eq_attr "unit" "i387")
344
           (plus (const_int 2)
345
                 (plus (attr "prefix_data16")
346
                       (attr "length_address")))]
347
         (plus (plus (attr "modrm")
348
                     (plus (attr "prefix_0f")
349
                           (plus (attr "prefix_rex")
350
                                 (const_int 1))))
351
               (plus (attr "prefix_rep")
352
                     (plus (attr "prefix_data16")
353
                           (plus (attr "length_immediate")
354
                                 (attr "length_address")))))))
355
 
356
;; The `memory' attribute is `none' if no memory is referenced, `load' or
357
;; `store' if there is a simple memory reference therein, or `unknown'
358
;; if the instruction is complex.
359
 
360
(define_attr "memory" "none,load,store,both,unknown"
361
  (cond [(eq_attr "type" "other,multi,str")
362
           (const_string "unknown")
363
         (eq_attr "type" "lea,fcmov,fpspc,cld")
364
           (const_string "none")
365
         (eq_attr "type" "fistp,leave")
366
           (const_string "both")
367
         (eq_attr "type" "frndint")
368
           (const_string "load")
369
         (eq_attr "type" "push")
370
           (if_then_else (match_operand 1 "memory_operand" "")
371
             (const_string "both")
372
             (const_string "store"))
373
         (eq_attr "type" "pop")
374
           (if_then_else (match_operand 0 "memory_operand" "")
375
             (const_string "both")
376
             (const_string "load"))
377
         (eq_attr "type" "setcc")
378
           (if_then_else (match_operand 0 "memory_operand" "")
379
             (const_string "store")
380
             (const_string "none"))
381
         (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
382
           (if_then_else (ior (match_operand 0 "memory_operand" "")
383
                              (match_operand 1 "memory_operand" ""))
384
             (const_string "load")
385
             (const_string "none"))
386
         (eq_attr "type" "ibr")
387
           (if_then_else (match_operand 0 "memory_operand" "")
388
             (const_string "load")
389
             (const_string "none"))
390
         (eq_attr "type" "call")
391
           (if_then_else (match_operand 0 "constant_call_address_operand" "")
392
             (const_string "none")
393
             (const_string "load"))
394
         (eq_attr "type" "callv")
395
           (if_then_else (match_operand 1 "constant_call_address_operand" "")
396
             (const_string "none")
397
             (const_string "load"))
398
         (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
399
              (match_operand 1 "memory_operand" ""))
400
           (const_string "both")
401
         (and (match_operand 0 "memory_operand" "")
402
              (match_operand 1 "memory_operand" ""))
403
           (const_string "both")
404
         (match_operand 0 "memory_operand" "")
405
           (const_string "store")
406
         (match_operand 1 "memory_operand" "")
407
           (const_string "load")
408
         (and (eq_attr "type"
409
                 "!alu1,negnot,ishift1,
410
                   imov,imovx,icmp,test,
411
                   fmov,fcmp,fsgn,
412
                   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
413
                   mmx,mmxmov,mmxcmp,mmxcvt")
414
              (match_operand 2 "memory_operand" ""))
415
           (const_string "load")
416
         (and (eq_attr "type" "icmov")
417
              (match_operand 3 "memory_operand" ""))
418
           (const_string "load")
419
        ]
420
        (const_string "none")))
421
 
422
;; Indicates if an instruction has both an immediate and a displacement.
423
 
424
(define_attr "imm_disp" "false,true,unknown"
425
  (cond [(eq_attr "type" "other,multi")
426
           (const_string "unknown")
427
         (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
428
              (and (match_operand 0 "memory_displacement_operand" "")
429
                   (match_operand 1 "immediate_operand" "")))
430
           (const_string "true")
431
         (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
432
              (and (match_operand 0 "memory_displacement_operand" "")
433
                   (match_operand 2 "immediate_operand" "")))
434
           (const_string "true")
435
        ]
436
        (const_string "false")))
437
 
438
;; Indicates if an FP operation has an integer source.
439
 
440
(define_attr "fp_int_src" "false,true"
441
  (const_string "false"))
442
 
443
;; Defines rounding mode of an FP operation.
444
 
445
(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
446
  (const_string "any"))
447
 
448
;; Describe a user's asm statement.
449
(define_asm_attributes
450
  [(set_attr "length" "128")
451
   (set_attr "type" "multi")])
452
 
453
;; All x87 floating point modes
454
(define_mode_macro X87MODEF [SF DF XF])
455
 
456
;; All integer modes handled by x87 fisttp operator.
457
(define_mode_macro X87MODEI [HI SI DI])
458
 
459
;; All integer modes handled by integer x87 operators.
460
(define_mode_macro X87MODEI12 [HI SI])
461
 
462
;; All SSE floating point modes
463
(define_mode_macro SSEMODEF [SF DF])
464
 
465
;; All integer modes handled by SSE cvtts?2si* operators.
466
(define_mode_macro SSEMODEI24 [SI DI])
467
 
468
 
469
;; Scheduling descriptions
470
 
471
(include "pentium.md")
472
(include "ppro.md")
473
(include "k6.md")
474
(include "athlon.md")
475
 
476
 
477
;; Operand and operator predicates and constraints
478
 
479
(include "predicates.md")
480
(include "constraints.md")
481
 
482
 
483
;; Compare instructions.
484
 
485
;; All compare insns have expanders that save the operands away without
486
;; actually generating RTL.  The bCOND or sCOND (emitted immediately
487
;; after the cmp) will actually emit the cmpM.
488
 
489
(define_expand "cmpti"
490
  [(set (reg:CC FLAGS_REG)
491
        (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492
                    (match_operand:TI 1 "x86_64_general_operand" "")))]
493
  "TARGET_64BIT"
494
{
495
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496
    operands[0] = force_reg (TImode, operands[0]);
497
  ix86_compare_op0 = operands[0];
498
  ix86_compare_op1 = operands[1];
499
  DONE;
500
})
501
 
502
(define_expand "cmpdi"
503
  [(set (reg:CC FLAGS_REG)
504
        (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505
                    (match_operand:DI 1 "x86_64_general_operand" "")))]
506
  ""
507
{
508
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509
    operands[0] = force_reg (DImode, operands[0]);
510
  ix86_compare_op0 = operands[0];
511
  ix86_compare_op1 = operands[1];
512
  DONE;
513
})
514
 
515
(define_expand "cmpsi"
516
  [(set (reg:CC FLAGS_REG)
517
        (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518
                    (match_operand:SI 1 "general_operand" "")))]
519
  ""
520
{
521
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522
    operands[0] = force_reg (SImode, operands[0]);
523
  ix86_compare_op0 = operands[0];
524
  ix86_compare_op1 = operands[1];
525
  DONE;
526
})
527
 
528
(define_expand "cmphi"
529
  [(set (reg:CC FLAGS_REG)
530
        (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531
                    (match_operand:HI 1 "general_operand" "")))]
532
  ""
533
{
534
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535
    operands[0] = force_reg (HImode, operands[0]);
536
  ix86_compare_op0 = operands[0];
537
  ix86_compare_op1 = operands[1];
538
  DONE;
539
})
540
 
541
(define_expand "cmpqi"
542
  [(set (reg:CC FLAGS_REG)
543
        (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544
                    (match_operand:QI 1 "general_operand" "")))]
545
  "TARGET_QIMODE_MATH"
546
{
547
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548
    operands[0] = force_reg (QImode, operands[0]);
549
  ix86_compare_op0 = operands[0];
550
  ix86_compare_op1 = operands[1];
551
  DONE;
552
})
553
 
554
(define_insn "cmpdi_ccno_1_rex64"
555
  [(set (reg FLAGS_REG)
556
        (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557
                 (match_operand:DI 1 "const0_operand" "n,n")))]
558
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559
  "@
560
   test{q}\t{%0, %0|%0, %0}
561
   cmp{q}\t{%1, %0|%0, %1}"
562
  [(set_attr "type" "test,icmp")
563
   (set_attr "length_immediate" "0,1")
564
   (set_attr "mode" "DI")])
565
 
566
(define_insn "*cmpdi_minus_1_rex64"
567
  [(set (reg FLAGS_REG)
568
        (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569
                           (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570
                 (const_int 0)))]
571
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572
  "cmp{q}\t{%1, %0|%0, %1}"
573
  [(set_attr "type" "icmp")
574
   (set_attr "mode" "DI")])
575
 
576
(define_expand "cmpdi_1_rex64"
577
  [(set (reg:CC FLAGS_REG)
578
        (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579
                    (match_operand:DI 1 "general_operand" "")))]
580
  "TARGET_64BIT"
581
  "")
582
 
583
(define_insn "cmpdi_1_insn_rex64"
584
  [(set (reg FLAGS_REG)
585
        (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586
                 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588
  "cmp{q}\t{%1, %0|%0, %1}"
589
  [(set_attr "type" "icmp")
590
   (set_attr "mode" "DI")])
591
 
592
 
593
(define_insn "*cmpsi_ccno_1"
594
  [(set (reg FLAGS_REG)
595
        (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596
                 (match_operand:SI 1 "const0_operand" "n,n")))]
597
  "ix86_match_ccmode (insn, CCNOmode)"
598
  "@
599
   test{l}\t{%0, %0|%0, %0}
600
   cmp{l}\t{%1, %0|%0, %1}"
601
  [(set_attr "type" "test,icmp")
602
   (set_attr "length_immediate" "0,1")
603
   (set_attr "mode" "SI")])
604
 
605
(define_insn "*cmpsi_minus_1"
606
  [(set (reg FLAGS_REG)
607
        (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608
                           (match_operand:SI 1 "general_operand" "ri,mr"))
609
                 (const_int 0)))]
610
  "ix86_match_ccmode (insn, CCGOCmode)"
611
  "cmp{l}\t{%1, %0|%0, %1}"
612
  [(set_attr "type" "icmp")
613
   (set_attr "mode" "SI")])
614
 
615
(define_expand "cmpsi_1"
616
  [(set (reg:CC FLAGS_REG)
617
        (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618
                    (match_operand:SI 1 "general_operand" "ri,mr")))]
619
  ""
620
  "")
621
 
622
(define_insn "*cmpsi_1_insn"
623
  [(set (reg FLAGS_REG)
624
        (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625
                 (match_operand:SI 1 "general_operand" "ri,mr")))]
626
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627
    && ix86_match_ccmode (insn, CCmode)"
628
  "cmp{l}\t{%1, %0|%0, %1}"
629
  [(set_attr "type" "icmp")
630
   (set_attr "mode" "SI")])
631
 
632
(define_insn "*cmphi_ccno_1"
633
  [(set (reg FLAGS_REG)
634
        (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635
                 (match_operand:HI 1 "const0_operand" "n,n")))]
636
  "ix86_match_ccmode (insn, CCNOmode)"
637
  "@
638
   test{w}\t{%0, %0|%0, %0}
639
   cmp{w}\t{%1, %0|%0, %1}"
640
  [(set_attr "type" "test,icmp")
641
   (set_attr "length_immediate" "0,1")
642
   (set_attr "mode" "HI")])
643
 
644
(define_insn "*cmphi_minus_1"
645
  [(set (reg FLAGS_REG)
646
        (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647
                           (match_operand:HI 1 "general_operand" "ri,mr"))
648
                 (const_int 0)))]
649
  "ix86_match_ccmode (insn, CCGOCmode)"
650
  "cmp{w}\t{%1, %0|%0, %1}"
651
  [(set_attr "type" "icmp")
652
   (set_attr "mode" "HI")])
653
 
654
(define_insn "*cmphi_1"
655
  [(set (reg FLAGS_REG)
656
        (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657
                 (match_operand:HI 1 "general_operand" "ri,mr")))]
658
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659
   && ix86_match_ccmode (insn, CCmode)"
660
  "cmp{w}\t{%1, %0|%0, %1}"
661
  [(set_attr "type" "icmp")
662
   (set_attr "mode" "HI")])
663
 
664
(define_insn "*cmpqi_ccno_1"
665
  [(set (reg FLAGS_REG)
666
        (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667
                 (match_operand:QI 1 "const0_operand" "n,n")))]
668
  "ix86_match_ccmode (insn, CCNOmode)"
669
  "@
670
   test{b}\t{%0, %0|%0, %0}
671
   cmp{b}\t{$0, %0|%0, 0}"
672
  [(set_attr "type" "test,icmp")
673
   (set_attr "length_immediate" "0,1")
674
   (set_attr "mode" "QI")])
675
 
676
(define_insn "*cmpqi_1"
677
  [(set (reg FLAGS_REG)
678
        (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679
                 (match_operand:QI 1 "general_operand" "qi,mq")))]
680
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681
    && ix86_match_ccmode (insn, CCmode)"
682
  "cmp{b}\t{%1, %0|%0, %1}"
683
  [(set_attr "type" "icmp")
684
   (set_attr "mode" "QI")])
685
 
686
(define_insn "*cmpqi_minus_1"
687
  [(set (reg FLAGS_REG)
688
        (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689
                           (match_operand:QI 1 "general_operand" "qi,mq"))
690
                 (const_int 0)))]
691
  "ix86_match_ccmode (insn, CCGOCmode)"
692
  "cmp{b}\t{%1, %0|%0, %1}"
693
  [(set_attr "type" "icmp")
694
   (set_attr "mode" "QI")])
695
 
696
(define_insn "*cmpqi_ext_1"
697
  [(set (reg FLAGS_REG)
698
        (compare
699
          (match_operand:QI 0 "general_operand" "Qm")
700
          (subreg:QI
701
            (zero_extract:SI
702
              (match_operand 1 "ext_register_operand" "Q")
703
              (const_int 8)
704
              (const_int 8)) 0)))]
705
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706
  "cmp{b}\t{%h1, %0|%0, %h1}"
707
  [(set_attr "type" "icmp")
708
   (set_attr "mode" "QI")])
709
 
710
(define_insn "*cmpqi_ext_1_rex64"
711
  [(set (reg FLAGS_REG)
712
        (compare
713
          (match_operand:QI 0 "register_operand" "Q")
714
          (subreg:QI
715
            (zero_extract:SI
716
              (match_operand 1 "ext_register_operand" "Q")
717
              (const_int 8)
718
              (const_int 8)) 0)))]
719
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720
  "cmp{b}\t{%h1, %0|%0, %h1}"
721
  [(set_attr "type" "icmp")
722
   (set_attr "mode" "QI")])
723
 
724
(define_insn "*cmpqi_ext_2"
725
  [(set (reg FLAGS_REG)
726
        (compare
727
          (subreg:QI
728
            (zero_extract:SI
729
              (match_operand 0 "ext_register_operand" "Q")
730
              (const_int 8)
731
              (const_int 8)) 0)
732
          (match_operand:QI 1 "const0_operand" "n")))]
733
  "ix86_match_ccmode (insn, CCNOmode)"
734
  "test{b}\t%h0, %h0"
735
  [(set_attr "type" "test")
736
   (set_attr "length_immediate" "0")
737
   (set_attr "mode" "QI")])
738
 
739
(define_expand "cmpqi_ext_3"
740
  [(set (reg:CC FLAGS_REG)
741
        (compare:CC
742
          (subreg:QI
743
            (zero_extract:SI
744
              (match_operand 0 "ext_register_operand" "")
745
              (const_int 8)
746
              (const_int 8)) 0)
747
          (match_operand:QI 1 "general_operand" "")))]
748
  ""
749
  "")
750
 
751
(define_insn "cmpqi_ext_3_insn"
752
  [(set (reg FLAGS_REG)
753
        (compare
754
          (subreg:QI
755
            (zero_extract:SI
756
              (match_operand 0 "ext_register_operand" "Q")
757
              (const_int 8)
758
              (const_int 8)) 0)
759
          (match_operand:QI 1 "general_operand" "Qmn")))]
760
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761
  "cmp{b}\t{%1, %h0|%h0, %1}"
762
  [(set_attr "type" "icmp")
763
   (set_attr "mode" "QI")])
764
 
765
(define_insn "cmpqi_ext_3_insn_rex64"
766
  [(set (reg FLAGS_REG)
767
        (compare
768
          (subreg:QI
769
            (zero_extract:SI
770
              (match_operand 0 "ext_register_operand" "Q")
771
              (const_int 8)
772
              (const_int 8)) 0)
773
          (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775
  "cmp{b}\t{%1, %h0|%h0, %1}"
776
  [(set_attr "type" "icmp")
777
   (set_attr "mode" "QI")])
778
 
779
(define_insn "*cmpqi_ext_4"
780
  [(set (reg FLAGS_REG)
781
        (compare
782
          (subreg:QI
783
            (zero_extract:SI
784
              (match_operand 0 "ext_register_operand" "Q")
785
              (const_int 8)
786
              (const_int 8)) 0)
787
          (subreg:QI
788
            (zero_extract:SI
789
              (match_operand 1 "ext_register_operand" "Q")
790
              (const_int 8)
791
              (const_int 8)) 0)))]
792
  "ix86_match_ccmode (insn, CCmode)"
793
  "cmp{b}\t{%h1, %h0|%h0, %h1}"
794
  [(set_attr "type" "icmp")
795
   (set_attr "mode" "QI")])
796
 
797
;; These implement float point compares.
798
;; %%% See if we can get away with VOIDmode operands on the actual insns,
799
;; which would allow mix and match FP modes on the compares.  Which is what
800
;; the old patterns did, but with many more of them.
801
 
802
(define_expand "cmpxf"
803
  [(set (reg:CC FLAGS_REG)
804
        (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805
                    (match_operand:XF 1 "nonmemory_operand" "")))]
806
  "TARGET_80387"
807
{
808
  ix86_compare_op0 = operands[0];
809
  ix86_compare_op1 = operands[1];
810
  DONE;
811
})
812
 
813
(define_expand "cmpdf"
814
  [(set (reg:CC FLAGS_REG)
815
        (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816
                    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818
{
819
  ix86_compare_op0 = operands[0];
820
  ix86_compare_op1 = operands[1];
821
  DONE;
822
})
823
 
824
(define_expand "cmpsf"
825
  [(set (reg:CC FLAGS_REG)
826
        (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827
                    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828
  "TARGET_80387 || TARGET_SSE_MATH"
829
{
830
  ix86_compare_op0 = operands[0];
831
  ix86_compare_op1 = operands[1];
832
  DONE;
833
})
834
 
835
;; FP compares, step 1:
836
;; Set the FP condition codes.
837
;;
838
;; CCFPmode     compare with exceptions
839
;; CCFPUmode    compare with no exceptions
840
 
841
;; We may not use "#" to split and emit these, since the REG_DEAD notes
842
;; used to manage the reg stack popping would not be preserved.
843
 
844
(define_insn "*cmpfp_0"
845
  [(set (match_operand:HI 0 "register_operand" "=a")
846
        (unspec:HI
847
          [(compare:CCFP
848
             (match_operand 1 "register_operand" "f")
849
             (match_operand 2 "const0_operand" "X"))]
850
        UNSPEC_FNSTSW))]
851
  "TARGET_80387
852
   && FLOAT_MODE_P (GET_MODE (operands[1]))
853
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854
  "* return output_fp_compare (insn, operands, 0, 0);"
855
  [(set_attr "type" "multi")
856
   (set_attr "unit" "i387")
857
   (set (attr "mode")
858
     (cond [(match_operand:SF 1 "" "")
859
              (const_string "SF")
860
            (match_operand:DF 1 "" "")
861
              (const_string "DF")
862
           ]
863
           (const_string "XF")))])
864
 
865
(define_insn "*cmpfp_sf"
866
  [(set (match_operand:HI 0 "register_operand" "=a")
867
        (unspec:HI
868
          [(compare:CCFP
869
             (match_operand:SF 1 "register_operand" "f")
870
             (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871
          UNSPEC_FNSTSW))]
872
  "TARGET_80387"
873
  "* return output_fp_compare (insn, operands, 0, 0);"
874
  [(set_attr "type" "multi")
875
   (set_attr "unit" "i387")
876
   (set_attr "mode" "SF")])
877
 
878
(define_insn "*cmpfp_df"
879
  [(set (match_operand:HI 0 "register_operand" "=a")
880
        (unspec:HI
881
          [(compare:CCFP
882
             (match_operand:DF 1 "register_operand" "f")
883
             (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884
          UNSPEC_FNSTSW))]
885
  "TARGET_80387"
886
  "* return output_fp_compare (insn, operands, 0, 0);"
887
  [(set_attr "type" "multi")
888
   (set_attr "unit" "i387")
889
   (set_attr "mode" "DF")])
890
 
891
(define_insn "*cmpfp_xf"
892
  [(set (match_operand:HI 0 "register_operand" "=a")
893
        (unspec:HI
894
          [(compare:CCFP
895
             (match_operand:XF 1 "register_operand" "f")
896
             (match_operand:XF 2 "register_operand" "f"))]
897
          UNSPEC_FNSTSW))]
898
  "TARGET_80387"
899
  "* return output_fp_compare (insn, operands, 0, 0);"
900
  [(set_attr "type" "multi")
901
   (set_attr "unit" "i387")
902
   (set_attr "mode" "XF")])
903
 
904
(define_insn "*cmpfp_u"
905
  [(set (match_operand:HI 0 "register_operand" "=a")
906
        (unspec:HI
907
          [(compare:CCFPU
908
             (match_operand 1 "register_operand" "f")
909
             (match_operand 2 "register_operand" "f"))]
910
          UNSPEC_FNSTSW))]
911
  "TARGET_80387
912
   && FLOAT_MODE_P (GET_MODE (operands[1]))
913
   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914
  "* return output_fp_compare (insn, operands, 0, 1);"
915
  [(set_attr "type" "multi")
916
   (set_attr "unit" "i387")
917
   (set (attr "mode")
918
     (cond [(match_operand:SF 1 "" "")
919
              (const_string "SF")
920
            (match_operand:DF 1 "" "")
921
              (const_string "DF")
922
           ]
923
           (const_string "XF")))])
924
 
925
(define_insn "*cmpfp_"
926
  [(set (match_operand:HI 0 "register_operand" "=a")
927
        (unspec:HI
928
          [(compare:CCFP
929
             (match_operand 1 "register_operand" "f")
930
             (match_operator 3 "float_operator"
931
               [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932
          UNSPEC_FNSTSW))]
933
  "TARGET_80387 && TARGET_USE_MODE_FIOP
934
   && FLOAT_MODE_P (GET_MODE (operands[1]))
935
   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936
  "* return output_fp_compare (insn, operands, 0, 0);"
937
  [(set_attr "type" "multi")
938
   (set_attr "unit" "i387")
939
   (set_attr "fp_int_src" "true")
940
   (set_attr "mode" "")])
941
 
942
;; FP compares, step 2
943
;; Move the fpsw to ax.
944
 
945
(define_insn "x86_fnstsw_1"
946
  [(set (match_operand:HI 0 "register_operand" "=a")
947
        (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948
  "TARGET_80387"
949
  "fnstsw\t%0"
950
  [(set_attr "length" "2")
951
   (set_attr "mode" "SI")
952
   (set_attr "unit" "i387")])
953
 
954
;; FP compares, step 3
955
;; Get ax into flags, general case.
956
 
957
(define_insn "x86_sahf_1"
958
  [(set (reg:CC FLAGS_REG)
959
        (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960
  "!TARGET_64BIT"
961
  "sahf"
962
  [(set_attr "length" "1")
963
   (set_attr "athlon_decode" "vector")
964
   (set_attr "mode" "SI")])
965
 
966
;; Pentium Pro can do steps 1 through 3 in one go.
967
 
968
(define_insn "*cmpfp_i_mixed"
969
  [(set (reg:CCFP FLAGS_REG)
970
        (compare:CCFP (match_operand 0 "register_operand" "f,x")
971
                      (match_operand 1 "nonimmediate_operand" "f,xm")))]
972
  "TARGET_MIX_SSE_I387
973
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975
  "* return output_fp_compare (insn, operands, 1, 0);"
976
  [(set_attr "type" "fcmp,ssecomi")
977
   (set (attr "mode")
978
     (if_then_else (match_operand:SF 1 "" "")
979
        (const_string "SF")
980
        (const_string "DF")))
981
   (set_attr "athlon_decode" "vector")])
982
 
983
(define_insn "*cmpfp_i_sse"
984
  [(set (reg:CCFP FLAGS_REG)
985
        (compare:CCFP (match_operand 0 "register_operand" "x")
986
                      (match_operand 1 "nonimmediate_operand" "xm")))]
987
  "TARGET_SSE_MATH
988
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990
  "* return output_fp_compare (insn, operands, 1, 0);"
991
  [(set_attr "type" "ssecomi")
992
   (set (attr "mode")
993
     (if_then_else (match_operand:SF 1 "" "")
994
        (const_string "SF")
995
        (const_string "DF")))
996
   (set_attr "athlon_decode" "vector")])
997
 
998
(define_insn "*cmpfp_i_i387"
999
  [(set (reg:CCFP FLAGS_REG)
1000
        (compare:CCFP (match_operand 0 "register_operand" "f")
1001
                      (match_operand 1 "register_operand" "f")))]
1002
  "TARGET_80387 && TARGET_CMOVE
1003
   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004
   && FLOAT_MODE_P (GET_MODE (operands[0]))
1005
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006
  "* return output_fp_compare (insn, operands, 1, 0);"
1007
  [(set_attr "type" "fcmp")
1008
   (set (attr "mode")
1009
     (cond [(match_operand:SF 1 "" "")
1010
              (const_string "SF")
1011
            (match_operand:DF 1 "" "")
1012
              (const_string "DF")
1013
           ]
1014
           (const_string "XF")))
1015
   (set_attr "athlon_decode" "vector")])
1016
 
1017
(define_insn "*cmpfp_iu_mixed"
1018
  [(set (reg:CCFPU FLAGS_REG)
1019
        (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1020
                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1021
  "TARGET_MIX_SSE_I387
1022
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024
  "* return output_fp_compare (insn, operands, 1, 1);"
1025
  [(set_attr "type" "fcmp,ssecomi")
1026
   (set (attr "mode")
1027
     (if_then_else (match_operand:SF 1 "" "")
1028
        (const_string "SF")
1029
        (const_string "DF")))
1030
   (set_attr "athlon_decode" "vector")])
1031
 
1032
(define_insn "*cmpfp_iu_sse"
1033
  [(set (reg:CCFPU FLAGS_REG)
1034
        (compare:CCFPU (match_operand 0 "register_operand" "x")
1035
                       (match_operand 1 "nonimmediate_operand" "xm")))]
1036
  "TARGET_SSE_MATH
1037
   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039
  "* return output_fp_compare (insn, operands, 1, 1);"
1040
  [(set_attr "type" "ssecomi")
1041
   (set (attr "mode")
1042
     (if_then_else (match_operand:SF 1 "" "")
1043
        (const_string "SF")
1044
        (const_string "DF")))
1045
   (set_attr "athlon_decode" "vector")])
1046
 
1047
(define_insn "*cmpfp_iu_387"
1048
  [(set (reg:CCFPU FLAGS_REG)
1049
        (compare:CCFPU (match_operand 0 "register_operand" "f")
1050
                       (match_operand 1 "register_operand" "f")))]
1051
  "TARGET_80387 && TARGET_CMOVE
1052
   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053
   && FLOAT_MODE_P (GET_MODE (operands[0]))
1054
   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055
  "* return output_fp_compare (insn, operands, 1, 1);"
1056
  [(set_attr "type" "fcmp")
1057
   (set (attr "mode")
1058
     (cond [(match_operand:SF 1 "" "")
1059
              (const_string "SF")
1060
            (match_operand:DF 1 "" "")
1061
              (const_string "DF")
1062
           ]
1063
           (const_string "XF")))
1064
   (set_attr "athlon_decode" "vector")])
1065
 
1066
;; Move instructions.
1067
 
1068
;; General case of fullword move.
1069
 
1070
(define_expand "movsi"
1071
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072
        (match_operand:SI 1 "general_operand" ""))]
1073
  ""
1074
  "ix86_expand_move (SImode, operands); DONE;")
1075
 
1076
;; Push/pop instructions.  They are separate since autoinc/dec is not a
1077
;; general_operand.
1078
;;
1079
;; %%% We don't use a post-inc memory reference because x86 is not a
1080
;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081
;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082
;; targets without our curiosities, and it is just as easy to represent
1083
;; this differently.
1084
 
1085
(define_insn "*pushsi2"
1086
  [(set (match_operand:SI 0 "push_operand" "=<")
1087
        (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088
  "!TARGET_64BIT"
1089
  "push{l}\t%1"
1090
  [(set_attr "type" "push")
1091
   (set_attr "mode" "SI")])
1092
 
1093
;; For 64BIT abi we always round up to 8 bytes.
1094
(define_insn "*pushsi2_rex64"
1095
  [(set (match_operand:SI 0 "push_operand" "=X")
1096
        (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097
  "TARGET_64BIT"
1098
  "push{q}\t%q1"
1099
  [(set_attr "type" "push")
1100
   (set_attr "mode" "SI")])
1101
 
1102
(define_insn "*pushsi2_prologue"
1103
  [(set (match_operand:SI 0 "push_operand" "=<")
1104
        (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105
   (clobber (mem:BLK (scratch)))]
1106
  "!TARGET_64BIT"
1107
  "push{l}\t%1"
1108
  [(set_attr "type" "push")
1109
   (set_attr "mode" "SI")])
1110
 
1111
(define_insn "*popsi1_epilogue"
1112
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113
        (mem:SI (reg:SI SP_REG)))
1114
   (set (reg:SI SP_REG)
1115
        (plus:SI (reg:SI SP_REG) (const_int 4)))
1116
   (clobber (mem:BLK (scratch)))]
1117
  "!TARGET_64BIT"
1118
  "pop{l}\t%0"
1119
  [(set_attr "type" "pop")
1120
   (set_attr "mode" "SI")])
1121
 
1122
(define_insn "popsi1"
1123
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124
        (mem:SI (reg:SI SP_REG)))
1125
   (set (reg:SI SP_REG)
1126
        (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127
  "!TARGET_64BIT"
1128
  "pop{l}\t%0"
1129
  [(set_attr "type" "pop")
1130
   (set_attr "mode" "SI")])
1131
 
1132
(define_insn "*movsi_xor"
1133
  [(set (match_operand:SI 0 "register_operand" "=r")
1134
        (match_operand:SI 1 "const0_operand" "i"))
1135
   (clobber (reg:CC FLAGS_REG))]
1136
  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137
  "xor{l}\t{%0, %0|%0, %0}"
1138
  [(set_attr "type" "alu1")
1139
   (set_attr "mode" "SI")
1140
   (set_attr "length_immediate" "0")])
1141
 
1142
(define_insn "*movsi_or"
1143
  [(set (match_operand:SI 0 "register_operand" "=r")
1144
        (match_operand:SI 1 "immediate_operand" "i"))
1145
   (clobber (reg:CC FLAGS_REG))]
1146
  "reload_completed
1147
   && operands[1] == constm1_rtx
1148
   && (TARGET_PENTIUM || optimize_size)"
1149
{
1150
  operands[1] = constm1_rtx;
1151
  return "or{l}\t{%1, %0|%0, %1}";
1152
}
1153
  [(set_attr "type" "alu1")
1154
   (set_attr "mode" "SI")
1155
   (set_attr "length_immediate" "1")])
1156
 
1157
(define_insn "*movsi_1"
1158
  [(set (match_operand:SI 0 "nonimmediate_operand"
1159
                        "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160
        (match_operand:SI 1 "general_operand"
1161
                        "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1162
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163
{
1164
  switch (get_attr_type (insn))
1165
    {
1166
    case TYPE_SSELOG1:
1167
      if (get_attr_mode (insn) == MODE_TI)
1168
        return "pxor\t%0, %0";
1169
      return "xorps\t%0, %0";
1170
 
1171
    case TYPE_SSEMOV:
1172
      switch (get_attr_mode (insn))
1173
        {
1174
        case MODE_TI:
1175
          return "movdqa\t{%1, %0|%0, %1}";
1176
        case MODE_V4SF:
1177
          return "movaps\t{%1, %0|%0, %1}";
1178
        case MODE_SI:
1179
          return "movd\t{%1, %0|%0, %1}";
1180
        case MODE_SF:
1181
          return "movss\t{%1, %0|%0, %1}";
1182
        default:
1183
          gcc_unreachable ();
1184
        }
1185
 
1186
    case TYPE_MMXADD:
1187
      return "pxor\t%0, %0";
1188
 
1189
    case TYPE_MMXMOV:
1190
      if (get_attr_mode (insn) == MODE_DI)
1191
        return "movq\t{%1, %0|%0, %1}";
1192
      return "movd\t{%1, %0|%0, %1}";
1193
 
1194
    case TYPE_LEA:
1195
      return "lea{l}\t{%1, %0|%0, %1}";
1196
 
1197
    default:
1198
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199
      return "mov{l}\t{%1, %0|%0, %1}";
1200
    }
1201
}
1202
  [(set (attr "type")
1203
     (cond [(eq_attr "alternative" "2")
1204
              (const_string "mmxadd")
1205
            (eq_attr "alternative" "3,4,5")
1206
              (const_string "mmxmov")
1207
            (eq_attr "alternative" "6")
1208
              (const_string "sselog1")
1209
            (eq_attr "alternative" "7,8,9,10,11")
1210
              (const_string "ssemov")
1211
            (match_operand:DI 1 "pic_32bit_operand" "")
1212
              (const_string "lea")
1213
           ]
1214
           (const_string "imov")))
1215
   (set (attr "mode")
1216
     (cond [(eq_attr "alternative" "2,3")
1217
              (const_string "DI")
1218
            (eq_attr "alternative" "6,7")
1219
              (if_then_else
1220
                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221
                (const_string "V4SF")
1222
                (const_string "TI"))
1223
            (and (eq_attr "alternative" "8,9,10,11")
1224
                 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225
              (const_string "SF")
1226
           ]
1227
           (const_string "SI")))])
1228
 
1229
;; Stores and loads of ax to arbitrary constant address.
1230
;; We fake an second form of instruction to force reload to load address
1231
;; into register when rax is not available
1232
(define_insn "*movabssi_1_rex64"
1233
  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234
        (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236
  "@
1237
   movabs{l}\t{%1, %P0|%P0, %1}
1238
   mov{l}\t{%1, %a0|%a0, %1}"
1239
  [(set_attr "type" "imov")
1240
   (set_attr "modrm" "0,*")
1241
   (set_attr "length_address" "8,0")
1242
   (set_attr "length_immediate" "0,*")
1243
   (set_attr "memory" "store")
1244
   (set_attr "mode" "SI")])
1245
 
1246
(define_insn "*movabssi_2_rex64"
1247
  [(set (match_operand:SI 0 "register_operand" "=a,r")
1248
        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250
  "@
1251
   movabs{l}\t{%P1, %0|%0, %P1}
1252
   mov{l}\t{%a1, %0|%0, %a1}"
1253
  [(set_attr "type" "imov")
1254
   (set_attr "modrm" "0,*")
1255
   (set_attr "length_address" "8,0")
1256
   (set_attr "length_immediate" "0")
1257
   (set_attr "memory" "load")
1258
   (set_attr "mode" "SI")])
1259
 
1260
(define_insn "*swapsi"
1261
  [(set (match_operand:SI 0 "register_operand" "+r")
1262
        (match_operand:SI 1 "register_operand" "+r"))
1263
   (set (match_dup 1)
1264
        (match_dup 0))]
1265
  ""
1266
  "xchg{l}\t%1, %0"
1267
  [(set_attr "type" "imov")
1268
   (set_attr "mode" "SI")
1269
   (set_attr "pent_pair" "np")
1270
   (set_attr "athlon_decode" "vector")])
1271
 
1272
(define_expand "movhi"
1273
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274
        (match_operand:HI 1 "general_operand" ""))]
1275
  ""
1276
  "ix86_expand_move (HImode, operands); DONE;")
1277
 
1278
(define_insn "*pushhi2"
1279
  [(set (match_operand:HI 0 "push_operand" "=X")
1280
        (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281
  "!TARGET_64BIT"
1282
  "push{l}\t%k1"
1283
  [(set_attr "type" "push")
1284
   (set_attr "mode" "SI")])
1285
 
1286
;; For 64BIT abi we always round up to 8 bytes.
1287
(define_insn "*pushhi2_rex64"
1288
  [(set (match_operand:HI 0 "push_operand" "=X")
1289
        (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290
  "TARGET_64BIT"
1291
  "push{q}\t%q1"
1292
  [(set_attr "type" "push")
1293
   (set_attr "mode" "DI")])
1294
 
1295
(define_insn "*movhi_1"
1296
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297
        (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299
{
1300
  switch (get_attr_type (insn))
1301
    {
1302
    case TYPE_IMOVX:
1303
      /* movzwl is faster than movw on p2 due to partial word stalls,
1304
         though not as fast as an aligned movl.  */
1305
      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306
    default:
1307
      if (get_attr_mode (insn) == MODE_SI)
1308
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309
      else
1310
        return "mov{w}\t{%1, %0|%0, %1}";
1311
    }
1312
}
1313
  [(set (attr "type")
1314
     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315
              (const_string "imov")
1316
            (and (eq_attr "alternative" "0")
1317
                 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318
                          (const_int 0))
1319
                      (eq (symbol_ref "TARGET_HIMODE_MATH")
1320
                          (const_int 0))))
1321
              (const_string "imov")
1322
            (and (eq_attr "alternative" "1,2")
1323
                 (match_operand:HI 1 "aligned_operand" ""))
1324
              (const_string "imov")
1325
            (and (ne (symbol_ref "TARGET_MOVX")
1326
                     (const_int 0))
1327
                 (eq_attr "alternative" "0,2"))
1328
              (const_string "imovx")
1329
           ]
1330
           (const_string "imov")))
1331
    (set (attr "mode")
1332
      (cond [(eq_attr "type" "imovx")
1333
               (const_string "SI")
1334
             (and (eq_attr "alternative" "1,2")
1335
                  (match_operand:HI 1 "aligned_operand" ""))
1336
               (const_string "SI")
1337
             (and (eq_attr "alternative" "0")
1338
                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339
                           (const_int 0))
1340
                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1341
                           (const_int 0))))
1342
               (const_string "SI")
1343
            ]
1344
            (const_string "HI")))])
1345
 
1346
;; Stores and loads of ax to arbitrary constant address.
1347
;; We fake an second form of instruction to force reload to load address
1348
;; into register when rax is not available
1349
(define_insn "*movabshi_1_rex64"
1350
  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351
        (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353
  "@
1354
   movabs{w}\t{%1, %P0|%P0, %1}
1355
   mov{w}\t{%1, %a0|%a0, %1}"
1356
  [(set_attr "type" "imov")
1357
   (set_attr "modrm" "0,*")
1358
   (set_attr "length_address" "8,0")
1359
   (set_attr "length_immediate" "0,*")
1360
   (set_attr "memory" "store")
1361
   (set_attr "mode" "HI")])
1362
 
1363
(define_insn "*movabshi_2_rex64"
1364
  [(set (match_operand:HI 0 "register_operand" "=a,r")
1365
        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367
  "@
1368
   movabs{w}\t{%P1, %0|%0, %P1}
1369
   mov{w}\t{%a1, %0|%0, %a1}"
1370
  [(set_attr "type" "imov")
1371
   (set_attr "modrm" "0,*")
1372
   (set_attr "length_address" "8,0")
1373
   (set_attr "length_immediate" "0")
1374
   (set_attr "memory" "load")
1375
   (set_attr "mode" "HI")])
1376
 
1377
(define_insn "*swaphi_1"
1378
  [(set (match_operand:HI 0 "register_operand" "+r")
1379
        (match_operand:HI 1 "register_operand" "+r"))
1380
   (set (match_dup 1)
1381
        (match_dup 0))]
1382
  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383
  "xchg{l}\t%k1, %k0"
1384
  [(set_attr "type" "imov")
1385
   (set_attr "mode" "SI")
1386
   (set_attr "pent_pair" "np")
1387
   (set_attr "athlon_decode" "vector")])
1388
 
1389
(define_insn "*swaphi_2"
1390
  [(set (match_operand:HI 0 "register_operand" "+r")
1391
        (match_operand:HI 1 "register_operand" "+r"))
1392
   (set (match_dup 1)
1393
        (match_dup 0))]
1394
  "TARGET_PARTIAL_REG_STALL"
1395
  "xchg{w}\t%1, %0"
1396
  [(set_attr "type" "imov")
1397
   (set_attr "mode" "HI")
1398
   (set_attr "pent_pair" "np")
1399
   (set_attr "athlon_decode" "vector")])
1400
 
1401
(define_expand "movstricthi"
1402
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403
        (match_operand:HI 1 "general_operand" ""))]
1404
  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405
{
1406
  /* Don't generate memory->memory moves, go through a register */
1407
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408
    operands[1] = force_reg (HImode, operands[1]);
1409
})
1410
 
1411
(define_insn "*movstricthi_1"
1412
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413
        (match_operand:HI 1 "general_operand" "rn,m"))]
1414
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416
  "mov{w}\t{%1, %0|%0, %1}"
1417
  [(set_attr "type" "imov")
1418
   (set_attr "mode" "HI")])
1419
 
1420
(define_insn "*movstricthi_xor"
1421
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422
        (match_operand:HI 1 "const0_operand" "i"))
1423
   (clobber (reg:CC FLAGS_REG))]
1424
  "reload_completed
1425
   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426
  "xor{w}\t{%0, %0|%0, %0}"
1427
  [(set_attr "type" "alu1")
1428
   (set_attr "mode" "HI")
1429
   (set_attr "length_immediate" "0")])
1430
 
1431
(define_expand "movqi"
1432
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433
        (match_operand:QI 1 "general_operand" ""))]
1434
  ""
1435
  "ix86_expand_move (QImode, operands); DONE;")
1436
 
1437
;; emit_push_insn when it calls move_by_pieces requires an insn to
1438
;; "push a byte".  But actually we use pushl, which has the effect
1439
;; of rounding the amount pushed up to a word.
1440
 
1441
(define_insn "*pushqi2"
1442
  [(set (match_operand:QI 0 "push_operand" "=X")
1443
        (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444
  "!TARGET_64BIT"
1445
  "push{l}\t%k1"
1446
  [(set_attr "type" "push")
1447
   (set_attr "mode" "SI")])
1448
 
1449
;; For 64BIT abi we always round up to 8 bytes.
1450
(define_insn "*pushqi2_rex64"
1451
  [(set (match_operand:QI 0 "push_operand" "=X")
1452
        (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453
  "TARGET_64BIT"
1454
  "push{q}\t%q1"
1455
  [(set_attr "type" "push")
1456
   (set_attr "mode" "DI")])
1457
 
1458
;; Situation is quite tricky about when to choose full sized (SImode) move
1459
;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1460
;; partial register dependency machines (such as AMD Athlon), where QImode
1461
;; moves issue extra dependency and for partial register stalls machines
1462
;; that don't use QImode patterns (and QImode move cause stall on the next
1463
;; instruction).
1464
;;
1465
;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466
;; register stall machines with, where we use QImode instructions, since
1467
;; partial register stall can be caused there.  Then we use movzx.
1468
(define_insn "*movqi_1"
1469
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470
        (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1471
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472
{
1473
  switch (get_attr_type (insn))
1474
    {
1475
    case TYPE_IMOVX:
1476
      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477
      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478
    default:
1479
      if (get_attr_mode (insn) == MODE_SI)
1480
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481
      else
1482
        return "mov{b}\t{%1, %0|%0, %1}";
1483
    }
1484
}
1485
  [(set (attr "type")
1486
     (cond [(and (eq_attr "alternative" "5")
1487
                 (not (match_operand:QI 1 "aligned_operand" "")))
1488
              (const_string "imovx")
1489
            (ne (symbol_ref "optimize_size") (const_int 0))
1490
              (const_string "imov")
1491
            (and (eq_attr "alternative" "3")
1492
                 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493
                          (const_int 0))
1494
                      (eq (symbol_ref "TARGET_QIMODE_MATH")
1495
                          (const_int 0))))
1496
              (const_string "imov")
1497
            (eq_attr "alternative" "3,5")
1498
              (const_string "imovx")
1499
            (and (ne (symbol_ref "TARGET_MOVX")
1500
                     (const_int 0))
1501
                 (eq_attr "alternative" "2"))
1502
              (const_string "imovx")
1503
           ]
1504
           (const_string "imov")))
1505
   (set (attr "mode")
1506
      (cond [(eq_attr "alternative" "3,4,5")
1507
               (const_string "SI")
1508
             (eq_attr "alternative" "6")
1509
               (const_string "QI")
1510
             (eq_attr "type" "imovx")
1511
               (const_string "SI")
1512
             (and (eq_attr "type" "imov")
1513
                  (and (eq_attr "alternative" "0,1")
1514
                       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515
                                (const_int 0))
1516
                            (and (eq (symbol_ref "optimize_size")
1517
                                     (const_int 0))
1518
                                 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519
                                     (const_int 0))))))
1520
               (const_string "SI")
1521
             ;; Avoid partial register stalls when not using QImode arithmetic
1522
             (and (eq_attr "type" "imov")
1523
                  (and (eq_attr "alternative" "0,1")
1524
                       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525
                                (const_int 0))
1526
                            (eq (symbol_ref "TARGET_QIMODE_MATH")
1527
                                (const_int 0)))))
1528
               (const_string "SI")
1529
           ]
1530
           (const_string "QI")))])
1531
 
1532
(define_expand "reload_outqi"
1533
  [(parallel [(match_operand:QI 0 "" "=m")
1534
              (match_operand:QI 1 "register_operand" "r")
1535
              (match_operand:QI 2 "register_operand" "=&q")])]
1536
  ""
1537
{
1538
  rtx op0, op1, op2;
1539
  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1540
 
1541
  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542
  if (! q_regs_operand (op1, QImode))
1543
    {
1544
      emit_insn (gen_movqi (op2, op1));
1545
      op1 = op2;
1546
    }
1547
  emit_insn (gen_movqi (op0, op1));
1548
  DONE;
1549
})
1550
 
1551
(define_insn "*swapqi_1"
1552
  [(set (match_operand:QI 0 "register_operand" "+r")
1553
        (match_operand:QI 1 "register_operand" "+r"))
1554
   (set (match_dup 1)
1555
        (match_dup 0))]
1556
  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1557
  "xchg{l}\t%k1, %k0"
1558
  [(set_attr "type" "imov")
1559
   (set_attr "mode" "SI")
1560
   (set_attr "pent_pair" "np")
1561
   (set_attr "athlon_decode" "vector")])
1562
 
1563
(define_insn "*swapqi_2"
1564
  [(set (match_operand:QI 0 "register_operand" "+q")
1565
        (match_operand:QI 1 "register_operand" "+q"))
1566
   (set (match_dup 1)
1567
        (match_dup 0))]
1568
  "TARGET_PARTIAL_REG_STALL"
1569
  "xchg{b}\t%1, %0"
1570
  [(set_attr "type" "imov")
1571
   (set_attr "mode" "QI")
1572
   (set_attr "pent_pair" "np")
1573
   (set_attr "athlon_decode" "vector")])
1574
 
1575
(define_expand "movstrictqi"
1576
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577
        (match_operand:QI 1 "general_operand" ""))]
1578
  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1579
{
1580
  /* Don't generate memory->memory moves, go through a register.  */
1581
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582
    operands[1] = force_reg (QImode, operands[1]);
1583
})
1584
 
1585
(define_insn "*movstrictqi_1"
1586
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587
        (match_operand:QI 1 "general_operand" "*qn,m"))]
1588
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590
  "mov{b}\t{%1, %0|%0, %1}"
1591
  [(set_attr "type" "imov")
1592
   (set_attr "mode" "QI")])
1593
 
1594
(define_insn "*movstrictqi_xor"
1595
  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596
        (match_operand:QI 1 "const0_operand" "i"))
1597
   (clobber (reg:CC FLAGS_REG))]
1598
  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599
  "xor{b}\t{%0, %0|%0, %0}"
1600
  [(set_attr "type" "alu1")
1601
   (set_attr "mode" "QI")
1602
   (set_attr "length_immediate" "0")])
1603
 
1604
(define_insn "*movsi_extv_1"
1605
  [(set (match_operand:SI 0 "register_operand" "=R")
1606
        (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607
                         (const_int 8)
1608
                         (const_int 8)))]
1609
  ""
1610
  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611
  [(set_attr "type" "imovx")
1612
   (set_attr "mode" "SI")])
1613
 
1614
(define_insn "*movhi_extv_1"
1615
  [(set (match_operand:HI 0 "register_operand" "=R")
1616
        (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617
                         (const_int 8)
1618
                         (const_int 8)))]
1619
  ""
1620
  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621
  [(set_attr "type" "imovx")
1622
   (set_attr "mode" "SI")])
1623
 
1624
(define_insn "*movqi_extv_1"
1625
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627
                         (const_int 8)
1628
                         (const_int 8)))]
1629
  "!TARGET_64BIT"
1630
{
1631
  switch (get_attr_type (insn))
1632
    {
1633
    case TYPE_IMOVX:
1634
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635
    default:
1636
      return "mov{b}\t{%h1, %0|%0, %h1}";
1637
    }
1638
}
1639
  [(set (attr "type")
1640
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642
                             (ne (symbol_ref "TARGET_MOVX")
1643
                                 (const_int 0))))
1644
        (const_string "imovx")
1645
        (const_string "imov")))
1646
   (set (attr "mode")
1647
     (if_then_else (eq_attr "type" "imovx")
1648
        (const_string "SI")
1649
        (const_string "QI")))])
1650
 
1651
(define_insn "*movqi_extv_1_rex64"
1652
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653
        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654
                         (const_int 8)
1655
                         (const_int 8)))]
1656
  "TARGET_64BIT"
1657
{
1658
  switch (get_attr_type (insn))
1659
    {
1660
    case TYPE_IMOVX:
1661
      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662
    default:
1663
      return "mov{b}\t{%h1, %0|%0, %h1}";
1664
    }
1665
}
1666
  [(set (attr "type")
1667
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669
                             (ne (symbol_ref "TARGET_MOVX")
1670
                                 (const_int 0))))
1671
        (const_string "imovx")
1672
        (const_string "imov")))
1673
   (set (attr "mode")
1674
     (if_then_else (eq_attr "type" "imovx")
1675
        (const_string "SI")
1676
        (const_string "QI")))])
1677
 
1678
;; Stores and loads of ax to arbitrary constant address.
1679
;; We fake an second form of instruction to force reload to load address
1680
;; into register when rax is not available
1681
(define_insn "*movabsqi_1_rex64"
1682
  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683
        (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1685
  "@
1686
   movabs{b}\t{%1, %P0|%P0, %1}
1687
   mov{b}\t{%1, %a0|%a0, %1}"
1688
  [(set_attr "type" "imov")
1689
   (set_attr "modrm" "0,*")
1690
   (set_attr "length_address" "8,0")
1691
   (set_attr "length_immediate" "0,*")
1692
   (set_attr "memory" "store")
1693
   (set_attr "mode" "QI")])
1694
 
1695
(define_insn "*movabsqi_2_rex64"
1696
  [(set (match_operand:QI 0 "register_operand" "=a,r")
1697
        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1699
  "@
1700
   movabs{b}\t{%P1, %0|%0, %P1}
1701
   mov{b}\t{%a1, %0|%0, %a1}"
1702
  [(set_attr "type" "imov")
1703
   (set_attr "modrm" "0,*")
1704
   (set_attr "length_address" "8,0")
1705
   (set_attr "length_immediate" "0")
1706
   (set_attr "memory" "load")
1707
   (set_attr "mode" "QI")])
1708
 
1709
(define_insn "*movdi_extzv_1"
1710
  [(set (match_operand:DI 0 "register_operand" "=R")
1711
        (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712
                         (const_int 8)
1713
                         (const_int 8)))]
1714
  "TARGET_64BIT"
1715
  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716
  [(set_attr "type" "imovx")
1717
   (set_attr "mode" "DI")])
1718
 
1719
(define_insn "*movsi_extzv_1"
1720
  [(set (match_operand:SI 0 "register_operand" "=R")
1721
        (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722
                         (const_int 8)
1723
                         (const_int 8)))]
1724
  ""
1725
  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726
  [(set_attr "type" "imovx")
1727
   (set_attr "mode" "SI")])
1728
 
1729
(define_insn "*movqi_extzv_2"
1730
  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731
        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732
                                    (const_int 8)
1733
                                    (const_int 8)) 0))]
1734
  "!TARGET_64BIT"
1735
{
1736
  switch (get_attr_type (insn))
1737
    {
1738
    case TYPE_IMOVX:
1739
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1740
    default:
1741
      return "mov{b}\t{%h1, %0|%0, %h1}";
1742
    }
1743
}
1744
  [(set (attr "type")
1745
     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746
                        (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747
                             (ne (symbol_ref "TARGET_MOVX")
1748
                                 (const_int 0))))
1749
        (const_string "imovx")
1750
        (const_string "imov")))
1751
   (set (attr "mode")
1752
     (if_then_else (eq_attr "type" "imovx")
1753
        (const_string "SI")
1754
        (const_string "QI")))])
1755
 
1756
(define_insn "*movqi_extzv_2_rex64"
1757
  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758
        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759
                                    (const_int 8)
1760
                                    (const_int 8)) 0))]
1761
  "TARGET_64BIT"
1762
{
1763
  switch (get_attr_type (insn))
1764
    {
1765
    case TYPE_IMOVX:
1766
      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767
    default:
1768
      return "mov{b}\t{%h1, %0|%0, %h1}";
1769
    }
1770
}
1771
  [(set (attr "type")
1772
     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773
                        (ne (symbol_ref "TARGET_MOVX")
1774
                            (const_int 0)))
1775
        (const_string "imovx")
1776
        (const_string "imov")))
1777
   (set (attr "mode")
1778
     (if_then_else (eq_attr "type" "imovx")
1779
        (const_string "SI")
1780
        (const_string "QI")))])
1781
 
1782
(define_insn "movsi_insv_1"
1783
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784
                         (const_int 8)
1785
                         (const_int 8))
1786
        (match_operand:SI 1 "general_operand" "Qmn"))]
1787
  "!TARGET_64BIT"
1788
  "mov{b}\t{%b1, %h0|%h0, %b1}"
1789
  [(set_attr "type" "imov")
1790
   (set_attr "mode" "QI")])
1791
 
1792
(define_insn "movdi_insv_1_rex64"
1793
  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794
                         (const_int 8)
1795
                         (const_int 8))
1796
        (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1797
  "TARGET_64BIT"
1798
  "mov{b}\t{%b1, %h0|%h0, %b1}"
1799
  [(set_attr "type" "imov")
1800
   (set_attr "mode" "QI")])
1801
 
1802
(define_insn "*movqi_insv_2"
1803
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804
                         (const_int 8)
1805
                         (const_int 8))
1806
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807
                     (const_int 8)))]
1808
  ""
1809
  "mov{b}\t{%h1, %h0|%h0, %h1}"
1810
  [(set_attr "type" "imov")
1811
   (set_attr "mode" "QI")])
1812
 
1813
(define_expand "movdi"
1814
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815
        (match_operand:DI 1 "general_operand" ""))]
1816
  ""
1817
  "ix86_expand_move (DImode, operands); DONE;")
1818
 
1819
(define_insn "*pushdi"
1820
  [(set (match_operand:DI 0 "push_operand" "=<")
1821
        (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822
  "!TARGET_64BIT"
1823
  "#")
1824
 
1825
(define_insn "*pushdi2_rex64"
1826
  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827
        (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828
  "TARGET_64BIT"
1829
  "@
1830
   push{q}\t%1
1831
   #"
1832
  [(set_attr "type" "push,multi")
1833
   (set_attr "mode" "DI")])
1834
 
1835
;; Convert impossible pushes of immediate to existing instructions.
1836
;; First try to get scratch register and go through it.  In case this
1837
;; fails, push sign extended lower part first and then overwrite
1838
;; upper part by 32bit move.
1839
(define_peephole2
1840
  [(match_scratch:DI 2 "r")
1841
   (set (match_operand:DI 0 "push_operand" "")
1842
        (match_operand:DI 1 "immediate_operand" ""))]
1843
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844
   && !x86_64_immediate_operand (operands[1], DImode)"
1845
  [(set (match_dup 2) (match_dup 1))
1846
   (set (match_dup 0) (match_dup 2))]
1847
  "")
1848
 
1849
;; We need to define this as both peepholer and splitter for case
1850
;; peephole2 pass is not run.
1851
;; "&& 1" is needed to keep it from matching the previous pattern.
1852
(define_peephole2
1853
  [(set (match_operand:DI 0 "push_operand" "")
1854
        (match_operand:DI 1 "immediate_operand" ""))]
1855
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857
  [(set (match_dup 0) (match_dup 1))
1858
   (set (match_dup 2) (match_dup 3))]
1859
  "split_di (operands + 1, 1, operands + 2, operands + 3);
1860
   operands[1] = gen_lowpart (DImode, operands[2]);
1861
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862
                                                    GEN_INT (4)));
1863
  ")
1864
 
1865
(define_split
1866
  [(set (match_operand:DI 0 "push_operand" "")
1867
        (match_operand:DI 1 "immediate_operand" ""))]
1868
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869
                    ? flow2_completed : reload_completed)
1870
   && !symbolic_operand (operands[1], DImode)
1871
   && !x86_64_immediate_operand (operands[1], DImode)"
1872
  [(set (match_dup 0) (match_dup 1))
1873
   (set (match_dup 2) (match_dup 3))]
1874
  "split_di (operands + 1, 1, operands + 2, operands + 3);
1875
   operands[1] = gen_lowpart (DImode, operands[2]);
1876
   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877
                                                    GEN_INT (4)));
1878
  ")
1879
 
1880
(define_insn "*pushdi2_prologue_rex64"
1881
  [(set (match_operand:DI 0 "push_operand" "=<")
1882
        (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883
   (clobber (mem:BLK (scratch)))]
1884
  "TARGET_64BIT"
1885
  "push{q}\t%1"
1886
  [(set_attr "type" "push")
1887
   (set_attr "mode" "DI")])
1888
 
1889
(define_insn "*popdi1_epilogue_rex64"
1890
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891
        (mem:DI (reg:DI SP_REG)))
1892
   (set (reg:DI SP_REG)
1893
        (plus:DI (reg:DI SP_REG) (const_int 8)))
1894
   (clobber (mem:BLK (scratch)))]
1895
  "TARGET_64BIT"
1896
  "pop{q}\t%0"
1897
  [(set_attr "type" "pop")
1898
   (set_attr "mode" "DI")])
1899
 
1900
(define_insn "popdi1"
1901
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902
        (mem:DI (reg:DI SP_REG)))
1903
   (set (reg:DI SP_REG)
1904
        (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905
  "TARGET_64BIT"
1906
  "pop{q}\t%0"
1907
  [(set_attr "type" "pop")
1908
   (set_attr "mode" "DI")])
1909
 
1910
(define_insn "*movdi_xor_rex64"
1911
  [(set (match_operand:DI 0 "register_operand" "=r")
1912
        (match_operand:DI 1 "const0_operand" "i"))
1913
   (clobber (reg:CC FLAGS_REG))]
1914
  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915
   && reload_completed"
1916
  "xor{l}\t{%k0, %k0|%k0, %k0}"
1917
  [(set_attr "type" "alu1")
1918
   (set_attr "mode" "SI")
1919
   (set_attr "length_immediate" "0")])
1920
 
1921
(define_insn "*movdi_or_rex64"
1922
  [(set (match_operand:DI 0 "register_operand" "=r")
1923
        (match_operand:DI 1 "const_int_operand" "i"))
1924
   (clobber (reg:CC FLAGS_REG))]
1925
  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926
   && reload_completed
1927
   && operands[1] == constm1_rtx"
1928
{
1929
  operands[1] = constm1_rtx;
1930
  return "or{q}\t{%1, %0|%0, %1}";
1931
}
1932
  [(set_attr "type" "alu1")
1933
   (set_attr "mode" "DI")
1934
   (set_attr "length_immediate" "1")])
1935
 
1936
(define_insn "*movdi_2"
1937
  [(set (match_operand:DI 0 "nonimmediate_operand"
1938
                                "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939
        (match_operand:DI 1 "general_operand"
1940
                                "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941
  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942
  "@
1943
   #
1944
   #
1945
   pxor\t%0, %0
1946
   movq\t{%1, %0|%0, %1}
1947
   movq\t{%1, %0|%0, %1}
1948
   pxor\t%0, %0
1949
   movq\t{%1, %0|%0, %1}
1950
   movdqa\t{%1, %0|%0, %1}
1951
   movq\t{%1, %0|%0, %1}
1952
   xorps\t%0, %0
1953
   movlps\t{%1, %0|%0, %1}
1954
   movaps\t{%1, %0|%0, %1}
1955
   movlps\t{%1, %0|%0, %1}"
1956
  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957
   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958
 
1959
(define_split
1960
  [(set (match_operand:DI 0 "push_operand" "")
1961
        (match_operand:DI 1 "general_operand" ""))]
1962
  "!TARGET_64BIT && reload_completed
1963
   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964
  [(const_int 0)]
1965
  "ix86_split_long_move (operands); DONE;")
1966
 
1967
;; %%% This multiword shite has got to go.
1968
(define_split
1969
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970
        (match_operand:DI 1 "general_operand" ""))]
1971
  "!TARGET_64BIT && reload_completed
1972
   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973
   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974
  [(const_int 0)]
1975
  "ix86_split_long_move (operands); DONE;")
1976
 
1977
(define_insn "*movdi_1_rex64"
1978
  [(set (match_operand:DI 0 "nonimmediate_operand"
1979
                "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980
        (match_operand:DI 1 "general_operand"
1981
                "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982
  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983
{
1984
  switch (get_attr_type (insn))
1985
    {
1986
    case TYPE_SSECVT:
1987
      if (which_alternative == 13)
1988
        return "movq2dq\t{%1, %0|%0, %1}";
1989
      else
1990
        return "movdq2q\t{%1, %0|%0, %1}";
1991
    case TYPE_SSEMOV:
1992
      if (get_attr_mode (insn) == MODE_TI)
1993
          return "movdqa\t{%1, %0|%0, %1}";
1994
      /* FALLTHRU */
1995
    case TYPE_MMXMOV:
1996
      /* Moves from and into integer register is done using movd opcode with
1997
         REX prefix.  */
1998
      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999
          return "movd\t{%1, %0|%0, %1}";
2000
      return "movq\t{%1, %0|%0, %1}";
2001
    case TYPE_SSELOG1:
2002
    case TYPE_MMXADD:
2003
      return "pxor\t%0, %0";
2004
    case TYPE_MULTI:
2005
      return "#";
2006
    case TYPE_LEA:
2007
      return "lea{q}\t{%a1, %0|%0, %a1}";
2008
    default:
2009
      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010
      if (get_attr_mode (insn) == MODE_SI)
2011
        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012
      else if (which_alternative == 2)
2013
        return "movabs{q}\t{%1, %0|%0, %1}";
2014
      else
2015
        return "mov{q}\t{%1, %0|%0, %1}";
2016
    }
2017
}
2018
  [(set (attr "type")
2019
     (cond [(eq_attr "alternative" "5")
2020
              (const_string "mmxadd")
2021
            (eq_attr "alternative" "6,7,8")
2022
              (const_string "mmxmov")
2023
            (eq_attr "alternative" "9")
2024
              (const_string "sselog1")
2025
            (eq_attr "alternative" "10,11,12")
2026
              (const_string "ssemov")
2027
            (eq_attr "alternative" "13,14")
2028
              (const_string "ssecvt")
2029
            (eq_attr "alternative" "4")
2030
              (const_string "multi")
2031
            (match_operand:DI 1 "pic_32bit_operand" "")
2032
              (const_string "lea")
2033
           ]
2034
           (const_string "imov")))
2035
   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036
   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037
   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2038
 
2039
;; Stores and loads of ax to arbitrary constant address.
2040
;; We fake an second form of instruction to force reload to load address
2041
;; into register when rax is not available
2042
(define_insn "*movabsdi_1_rex64"
2043
  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044
        (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045
  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046
  "@
2047
   movabs{q}\t{%1, %P0|%P0, %1}
2048
   mov{q}\t{%1, %a0|%a0, %1}"
2049
  [(set_attr "type" "imov")
2050
   (set_attr "modrm" "0,*")
2051
   (set_attr "length_address" "8,0")
2052
   (set_attr "length_immediate" "0,*")
2053
   (set_attr "memory" "store")
2054
   (set_attr "mode" "DI")])
2055
 
2056
(define_insn "*movabsdi_2_rex64"
2057
  [(set (match_operand:DI 0 "register_operand" "=a,r")
2058
        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059
  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060
  "@
2061
   movabs{q}\t{%P1, %0|%0, %P1}
2062
   mov{q}\t{%a1, %0|%0, %a1}"
2063
  [(set_attr "type" "imov")
2064
   (set_attr "modrm" "0,*")
2065
   (set_attr "length_address" "8,0")
2066
   (set_attr "length_immediate" "0")
2067
   (set_attr "memory" "load")
2068
   (set_attr "mode" "DI")])
2069
 
2070
;; Convert impossible stores of immediate to existing instructions.
2071
;; First try to get scratch register and go through it.  In case this
2072
;; fails, move by 32bit parts.
2073
(define_peephole2
2074
  [(match_scratch:DI 2 "r")
2075
   (set (match_operand:DI 0 "memory_operand" "")
2076
        (match_operand:DI 1 "immediate_operand" ""))]
2077
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078
   && !x86_64_immediate_operand (operands[1], DImode)"
2079
  [(set (match_dup 2) (match_dup 1))
2080
   (set (match_dup 0) (match_dup 2))]
2081
  "")
2082
 
2083
;; We need to define this as both peepholer and splitter for case
2084
;; peephole2 pass is not run.
2085
;; "&& 1" is needed to keep it from matching the previous pattern.
2086
(define_peephole2
2087
  [(set (match_operand:DI 0 "memory_operand" "")
2088
        (match_operand:DI 1 "immediate_operand" ""))]
2089
  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090
   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091
  [(set (match_dup 2) (match_dup 3))
2092
   (set (match_dup 4) (match_dup 5))]
2093
  "split_di (operands, 2, operands + 2, operands + 4);")
2094
 
2095
(define_split
2096
  [(set (match_operand:DI 0 "memory_operand" "")
2097
        (match_operand:DI 1 "immediate_operand" ""))]
2098
  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099
                    ? flow2_completed : reload_completed)
2100
   && !symbolic_operand (operands[1], DImode)
2101
   && !x86_64_immediate_operand (operands[1], DImode)"
2102
  [(set (match_dup 2) (match_dup 3))
2103
   (set (match_dup 4) (match_dup 5))]
2104
  "split_di (operands, 2, operands + 2, operands + 4);")
2105
 
2106
(define_insn "*swapdi_rex64"
2107
  [(set (match_operand:DI 0 "register_operand" "+r")
2108
        (match_operand:DI 1 "register_operand" "+r"))
2109
   (set (match_dup 1)
2110
        (match_dup 0))]
2111
  "TARGET_64BIT"
2112
  "xchg{q}\t%1, %0"
2113
  [(set_attr "type" "imov")
2114
   (set_attr "mode" "DI")
2115
   (set_attr "pent_pair" "np")
2116
   (set_attr "athlon_decode" "vector")])
2117
 
2118
(define_expand "movti"
2119
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120
        (match_operand:TI 1 "nonimmediate_operand" ""))]
2121
  "TARGET_SSE || TARGET_64BIT"
2122
{
2123
  if (TARGET_64BIT)
2124
    ix86_expand_move (TImode, operands);
2125
  else
2126
    ix86_expand_vector_move (TImode, operands);
2127
  DONE;
2128
})
2129
 
2130
(define_insn "*movti_internal"
2131
  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132
        (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133
  "TARGET_SSE && !TARGET_64BIT
2134
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2135
{
2136
  switch (which_alternative)
2137
    {
2138
    case 0:
2139
      if (get_attr_mode (insn) == MODE_V4SF)
2140
        return "xorps\t%0, %0";
2141
      else
2142
        return "pxor\t%0, %0";
2143
    case 1:
2144
    case 2:
2145
      if (get_attr_mode (insn) == MODE_V4SF)
2146
        return "movaps\t{%1, %0|%0, %1}";
2147
      else
2148
        return "movdqa\t{%1, %0|%0, %1}";
2149
    default:
2150
      gcc_unreachable ();
2151
    }
2152
}
2153
  [(set_attr "type" "sselog1,ssemov,ssemov")
2154
   (set (attr "mode")
2155
        (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156
                    (ne (symbol_ref "optimize_size") (const_int 0)))
2157
                 (const_string "V4SF")
2158
               (and (eq_attr "alternative" "2")
2159
                    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2160
                        (const_int 0)))
2161
                 (const_string "V4SF")]
2162
              (const_string "TI")))])
2163
 
2164
(define_insn "*movti_rex64"
2165
  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166
        (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167
  "TARGET_64BIT
2168
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169
{
2170
  switch (which_alternative)
2171
    {
2172
    case 0:
2173
    case 1:
2174
      return "#";
2175
    case 2:
2176
      if (get_attr_mode (insn) == MODE_V4SF)
2177
        return "xorps\t%0, %0";
2178
      else
2179
        return "pxor\t%0, %0";
2180
    case 3:
2181
    case 4:
2182
      if (get_attr_mode (insn) == MODE_V4SF)
2183
        return "movaps\t{%1, %0|%0, %1}";
2184
      else
2185
        return "movdqa\t{%1, %0|%0, %1}";
2186
    default:
2187
      gcc_unreachable ();
2188
    }
2189
}
2190
  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2191
   (set (attr "mode")
2192
        (cond [(eq_attr "alternative" "2,3")
2193
                 (if_then_else
2194
                   (ne (symbol_ref "optimize_size")
2195
                       (const_int 0))
2196
                   (const_string "V4SF")
2197
                   (const_string "TI"))
2198
               (eq_attr "alternative" "4")
2199
                 (if_then_else
2200
                   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201
                            (const_int 0))
2202
                        (ne (symbol_ref "optimize_size")
2203
                            (const_int 0)))
2204
                   (const_string "V4SF")
2205
                   (const_string "TI"))]
2206
               (const_string "DI")))])
2207
 
2208
(define_split
2209
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210
        (match_operand:TI 1 "general_operand" ""))]
2211
  "reload_completed && !SSE_REG_P (operands[0])
2212
   && !SSE_REG_P (operands[1])"
2213
  [(const_int 0)]
2214
  "ix86_split_long_move (operands); DONE;")
2215
 
2216
(define_expand "movsf"
2217
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218
        (match_operand:SF 1 "general_operand" ""))]
2219
  ""
2220
  "ix86_expand_move (SFmode, operands); DONE;")
2221
 
2222
(define_insn "*pushsf"
2223
  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224
        (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2225
  "!TARGET_64BIT"
2226
{
2227
  /* Anything else should be already split before reg-stack.  */
2228
  gcc_assert (which_alternative == 1);
2229
  return "push{l}\t%1";
2230
}
2231
  [(set_attr "type" "multi,push,multi")
2232
   (set_attr "unit" "i387,*,*")
2233
   (set_attr "mode" "SF,SI,SF")])
2234
 
2235
(define_insn "*pushsf_rex64"
2236
  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237
        (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2238
  "TARGET_64BIT"
2239
{
2240
  /* Anything else should be already split before reg-stack.  */
2241
  gcc_assert (which_alternative == 1);
2242
  return "push{q}\t%q1";
2243
}
2244
  [(set_attr "type" "multi,push,multi")
2245
   (set_attr "unit" "i387,*,*")
2246
   (set_attr "mode" "SF,DI,SF")])
2247
 
2248
(define_split
2249
  [(set (match_operand:SF 0 "push_operand" "")
2250
        (match_operand:SF 1 "memory_operand" ""))]
2251
  "reload_completed
2252
   && GET_CODE (operands[1]) == MEM
2253
   && constant_pool_reference_p (operands[1])"
2254
  [(set (match_dup 0)
2255
        (match_dup 1))]
2256
  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2257
 
2258
 
2259
;; %%% Kill this when call knows how to work this out.
2260
(define_split
2261
  [(set (match_operand:SF 0 "push_operand" "")
2262
        (match_operand:SF 1 "any_fp_register_operand" ""))]
2263
  "!TARGET_64BIT"
2264
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265
   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266
 
2267
(define_split
2268
  [(set (match_operand:SF 0 "push_operand" "")
2269
        (match_operand:SF 1 "any_fp_register_operand" ""))]
2270
  "TARGET_64BIT"
2271
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272
   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273
 
2274
(define_insn "*movsf_1"
2275
  [(set (match_operand:SF 0 "nonimmediate_operand"
2276
          "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2277
        (match_operand:SF 1 "general_operand"
2278
          "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2279
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280
   && (reload_in_progress || reload_completed
2281
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282
       || GET_CODE (operands[1]) != CONST_DOUBLE
2283
       || memory_operand (operands[0], SFmode))"
2284
{
2285
  switch (which_alternative)
2286
    {
2287
    case 0:
2288
      return output_387_reg_move (insn, operands);
2289
 
2290
    case 1:
2291
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292
        return "fstp%z0\t%y0";
2293
      else
2294
        return "fst%z0\t%y0";
2295
 
2296
    case 2:
2297
      return standard_80387_constant_opcode (operands[1]);
2298
 
2299
    case 3:
2300
    case 4:
2301
      return "mov{l}\t{%1, %0|%0, %1}";
2302
    case 5:
2303
      if (get_attr_mode (insn) == MODE_TI)
2304
        return "pxor\t%0, %0";
2305
      else
2306
        return "xorps\t%0, %0";
2307
    case 6:
2308
      if (get_attr_mode (insn) == MODE_V4SF)
2309
        return "movaps\t{%1, %0|%0, %1}";
2310
      else
2311
        return "movss\t{%1, %0|%0, %1}";
2312
    case 7:
2313
    case 8:
2314
      return "movss\t{%1, %0|%0, %1}";
2315
 
2316
    case 9:
2317
    case 10:
2318
      return "movd\t{%1, %0|%0, %1}";
2319
 
2320
    case 11:
2321
      return "movq\t{%1, %0|%0, %1}";
2322
 
2323
    default:
2324
      gcc_unreachable ();
2325
    }
2326
}
2327
  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328
   (set (attr "mode")
2329
        (cond [(eq_attr "alternative" "3,4,9,10")
2330
                 (const_string "SI")
2331
               (eq_attr "alternative" "5")
2332
                 (if_then_else
2333
                   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334
                                 (const_int 0))
2335
                             (ne (symbol_ref "TARGET_SSE2")
2336
                                 (const_int 0)))
2337
                        (eq (symbol_ref "optimize_size")
2338
                            (const_int 0)))
2339
                   (const_string "TI")
2340
                   (const_string "V4SF"))
2341
               /* For architectures resolving dependencies on
2342
                  whole SSE registers use APS move to break dependency
2343
                  chains, otherwise use short move to avoid extra work.
2344
 
2345
                  Do the same for architectures resolving dependencies on
2346
                  the parts.  While in DF mode it is better to always handle
2347
                  just register parts, the SF mode is different due to lack
2348
                  of instructions to load just part of the register.  It is
2349
                  better to maintain the whole registers in single format
2350
                  to avoid problems on using packed logical operations.  */
2351
               (eq_attr "alternative" "6")
2352
                 (if_then_else
2353
                   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354
                            (const_int 0))
2355
                        (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356
                            (const_int 0)))
2357
                   (const_string "V4SF")
2358
                   (const_string "SF"))
2359
               (eq_attr "alternative" "11")
2360
                 (const_string "DI")]
2361
               (const_string "SF")))])
2362
 
2363
(define_insn "*swapsf"
2364
  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365
        (match_operand:SF 1 "fp_register_operand" "+f"))
2366
   (set (match_dup 1)
2367
        (match_dup 0))]
2368
  "reload_completed || TARGET_80387"
2369
{
2370
  if (STACK_TOP_P (operands[0]))
2371
    return "fxch\t%1";
2372
  else
2373
    return "fxch\t%0";
2374
}
2375
  [(set_attr "type" "fxch")
2376
   (set_attr "mode" "SF")])
2377
 
2378
(define_expand "movdf"
2379
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380
        (match_operand:DF 1 "general_operand" ""))]
2381
  ""
2382
  "ix86_expand_move (DFmode, operands); DONE;")
2383
 
2384
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385
;; Size of pushdf using integer instructions is 2+2*memory operand size
2386
;; On the average, pushdf using integers can be still shorter.  Allow this
2387
;; pattern for optimize_size too.
2388
 
2389
(define_insn "*pushdf_nointeger"
2390
  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391
        (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2392
  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393
{
2394
  /* This insn should be already split before reg-stack.  */
2395
  gcc_unreachable ();
2396
}
2397
  [(set_attr "type" "multi")
2398
   (set_attr "unit" "i387,*,*,*")
2399
   (set_attr "mode" "DF,SI,SI,DF")])
2400
 
2401
(define_insn "*pushdf_integer"
2402
  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403
        (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2404
  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405
{
2406
  /* This insn should be already split before reg-stack.  */
2407
  gcc_unreachable ();
2408
}
2409
  [(set_attr "type" "multi")
2410
   (set_attr "unit" "i387,*,*")
2411
   (set_attr "mode" "DF,SI,DF")])
2412
 
2413
;; %%% Kill this when call knows how to work this out.
2414
(define_split
2415
  [(set (match_operand:DF 0 "push_operand" "")
2416
        (match_operand:DF 1 "any_fp_register_operand" ""))]
2417
  "!TARGET_64BIT && reload_completed"
2418
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419
   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420
  "")
2421
 
2422
(define_split
2423
  [(set (match_operand:DF 0 "push_operand" "")
2424
        (match_operand:DF 1 "any_fp_register_operand" ""))]
2425
  "TARGET_64BIT && reload_completed"
2426
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427
   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428
  "")
2429
 
2430
(define_split
2431
  [(set (match_operand:DF 0 "push_operand" "")
2432
        (match_operand:DF 1 "general_operand" ""))]
2433
  "reload_completed"
2434
  [(const_int 0)]
2435
  "ix86_split_long_move (operands); DONE;")
2436
 
2437
;; Moving is usually shorter when only FP registers are used. This separate
2438
;; movdf pattern avoids the use of integer registers for FP operations
2439
;; when optimizing for size.
2440
 
2441
(define_insn "*movdf_nointeger"
2442
  [(set (match_operand:DF 0 "nonimmediate_operand"
2443
                        "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2444
        (match_operand:DF 1 "general_operand"
2445
                        "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2446
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447
   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448
   && (reload_in_progress || reload_completed
2449
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450
       || GET_CODE (operands[1]) != CONST_DOUBLE
2451
       || memory_operand (operands[0], DFmode))"
2452
{
2453
  switch (which_alternative)
2454
    {
2455
    case 0:
2456
      return output_387_reg_move (insn, operands);
2457
 
2458
    case 1:
2459
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460
        return "fstp%z0\t%y0";
2461
      else
2462
        return "fst%z0\t%y0";
2463
 
2464
    case 2:
2465
      return standard_80387_constant_opcode (operands[1]);
2466
 
2467
    case 3:
2468
    case 4:
2469
      return "#";
2470
    case 5:
2471
      switch (get_attr_mode (insn))
2472
        {
2473
        case MODE_V4SF:
2474
          return "xorps\t%0, %0";
2475
        case MODE_V2DF:
2476
          return "xorpd\t%0, %0";
2477
        case MODE_TI:
2478
          return "pxor\t%0, %0";
2479
        default:
2480
          gcc_unreachable ();
2481
        }
2482
    case 6:
2483
    case 7:
2484
    case 8:
2485
      switch (get_attr_mode (insn))
2486
        {
2487
        case MODE_V4SF:
2488
          return "movaps\t{%1, %0|%0, %1}";
2489
        case MODE_V2DF:
2490
          return "movapd\t{%1, %0|%0, %1}";
2491
        case MODE_TI:
2492
          return "movdqa\t{%1, %0|%0, %1}";
2493
        case MODE_DI:
2494
          return "movq\t{%1, %0|%0, %1}";
2495
        case MODE_DF:
2496
          return "movsd\t{%1, %0|%0, %1}";
2497
        case MODE_V1DF:
2498
          return "movlpd\t{%1, %0|%0, %1}";
2499
        case MODE_V2SF:
2500
          return "movlps\t{%1, %0|%0, %1}";
2501
        default:
2502
          gcc_unreachable ();
2503
        }
2504
 
2505
    default:
2506
      gcc_unreachable ();
2507
    }
2508
}
2509
  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2510
   (set (attr "mode")
2511
        (cond [(eq_attr "alternative" "0,1,2")
2512
                 (const_string "DF")
2513
               (eq_attr "alternative" "3,4")
2514
                 (const_string "SI")
2515
 
2516
               /* For SSE1, we have many fewer alternatives.  */
2517
               (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518
                 (cond [(eq_attr "alternative" "5,6")
2519
                          (const_string "V4SF")
2520
                       ]
2521
                   (const_string "V2SF"))
2522
 
2523
               /* xorps is one byte shorter.  */
2524
               (eq_attr "alternative" "5")
2525
                 (cond [(ne (symbol_ref "optimize_size")
2526
                            (const_int 0))
2527
                          (const_string "V4SF")
2528
                        (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529
                            (const_int 0))
2530
                          (const_string "TI")
2531
                       ]
2532
                       (const_string "V2DF"))
2533
 
2534
               /* For architectures resolving dependencies on
2535
                  whole SSE registers use APD move to break dependency
2536
                  chains, otherwise use short move to avoid extra work.
2537
 
2538
                  movaps encodes one byte shorter.  */
2539
               (eq_attr "alternative" "6")
2540
                 (cond
2541
                   [(ne (symbol_ref "optimize_size")
2542
                        (const_int 0))
2543
                      (const_string "V4SF")
2544
                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545
                        (const_int 0))
2546
                      (const_string "V2DF")
2547
                   ]
2548
                   (const_string "DF"))
2549
               /* For architectures resolving dependencies on register
2550
                  parts we may avoid extra work to zero out upper part
2551
                  of register.  */
2552
               (eq_attr "alternative" "7")
2553
                 (if_then_else
2554
                   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555
                       (const_int 0))
2556
                   (const_string "V1DF")
2557
                   (const_string "DF"))
2558
              ]
2559
              (const_string "DF")))])
2560
 
2561
(define_insn "*movdf_integer"
2562
  [(set (match_operand:DF 0 "nonimmediate_operand"
2563
                "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2564
        (match_operand:DF 1 "general_operand"
2565
                "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2566
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567
   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568
   && (reload_in_progress || reload_completed
2569
       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570
       || GET_CODE (operands[1]) != CONST_DOUBLE
2571
       || memory_operand (operands[0], DFmode))"
2572
{
2573
  switch (which_alternative)
2574
    {
2575
    case 0:
2576
      return output_387_reg_move (insn, operands);
2577
 
2578
    case 1:
2579
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580
        return "fstp%z0\t%y0";
2581
      else
2582
        return "fst%z0\t%y0";
2583
 
2584
    case 2:
2585
      return standard_80387_constant_opcode (operands[1]);
2586
 
2587
    case 3:
2588
    case 4:
2589
      return "#";
2590
 
2591
    case 5:
2592
      switch (get_attr_mode (insn))
2593
        {
2594
        case MODE_V4SF:
2595
          return "xorps\t%0, %0";
2596
        case MODE_V2DF:
2597
          return "xorpd\t%0, %0";
2598
        case MODE_TI:
2599
          return "pxor\t%0, %0";
2600
        default:
2601
          gcc_unreachable ();
2602
        }
2603
    case 6:
2604
    case 7:
2605
    case 8:
2606
      switch (get_attr_mode (insn))
2607
        {
2608
        case MODE_V4SF:
2609
          return "movaps\t{%1, %0|%0, %1}";
2610
        case MODE_V2DF:
2611
          return "movapd\t{%1, %0|%0, %1}";
2612
        case MODE_TI:
2613
          return "movdqa\t{%1, %0|%0, %1}";
2614
        case MODE_DI:
2615
          return "movq\t{%1, %0|%0, %1}";
2616
        case MODE_DF:
2617
          return "movsd\t{%1, %0|%0, %1}";
2618
        case MODE_V1DF:
2619
          return "movlpd\t{%1, %0|%0, %1}";
2620
        case MODE_V2SF:
2621
          return "movlps\t{%1, %0|%0, %1}";
2622
        default:
2623
          gcc_unreachable ();
2624
        }
2625
 
2626
    default:
2627
      gcc_unreachable();
2628
    }
2629
}
2630
  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2631
   (set (attr "mode")
2632
        (cond [(eq_attr "alternative" "0,1,2")
2633
                 (const_string "DF")
2634
               (eq_attr "alternative" "3,4")
2635
                 (const_string "SI")
2636
 
2637
               /* For SSE1, we have many fewer alternatives.  */
2638
               (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639
                 (cond [(eq_attr "alternative" "5,6")
2640
                          (const_string "V4SF")
2641
                       ]
2642
                   (const_string "V2SF"))
2643
 
2644
               /* xorps is one byte shorter.  */
2645
               (eq_attr "alternative" "5")
2646
                 (cond [(ne (symbol_ref "optimize_size")
2647
                            (const_int 0))
2648
                          (const_string "V4SF")
2649
                        (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650
                            (const_int 0))
2651
                          (const_string "TI")
2652
                       ]
2653
                       (const_string "V2DF"))
2654
 
2655
               /* For architectures resolving dependencies on
2656
                  whole SSE registers use APD move to break dependency
2657
                  chains, otherwise use short move to avoid extra work.
2658
 
2659
                  movaps encodes one byte shorter.  */
2660
               (eq_attr "alternative" "6")
2661
                 (cond
2662
                   [(ne (symbol_ref "optimize_size")
2663
                        (const_int 0))
2664
                      (const_string "V4SF")
2665
                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666
                        (const_int 0))
2667
                      (const_string "V2DF")
2668
                   ]
2669
                   (const_string "DF"))
2670
               /* For architectures resolving dependencies on register
2671
                  parts we may avoid extra work to zero out upper part
2672
                  of register.  */
2673
               (eq_attr "alternative" "7")
2674
                 (if_then_else
2675
                   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676
                       (const_int 0))
2677
                   (const_string "V1DF")
2678
                   (const_string "DF"))
2679
              ]
2680
              (const_string "DF")))])
2681
 
2682
(define_split
2683
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684
        (match_operand:DF 1 "general_operand" ""))]
2685
  "reload_completed
2686
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687
   && ! (ANY_FP_REG_P (operands[0]) ||
2688
         (GET_CODE (operands[0]) == SUBREG
2689
          && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690
   && ! (ANY_FP_REG_P (operands[1]) ||
2691
         (GET_CODE (operands[1]) == SUBREG
2692
          && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693
  [(const_int 0)]
2694
  "ix86_split_long_move (operands); DONE;")
2695
 
2696
(define_insn "*swapdf"
2697
  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698
        (match_operand:DF 1 "fp_register_operand" "+f"))
2699
   (set (match_dup 1)
2700
        (match_dup 0))]
2701
  "reload_completed || TARGET_80387"
2702
{
2703
  if (STACK_TOP_P (operands[0]))
2704
    return "fxch\t%1";
2705
  else
2706
    return "fxch\t%0";
2707
}
2708
  [(set_attr "type" "fxch")
2709
   (set_attr "mode" "DF")])
2710
 
2711
(define_expand "movxf"
2712
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713
        (match_operand:XF 1 "general_operand" ""))]
2714
  ""
2715
  "ix86_expand_move (XFmode, operands); DONE;")
2716
 
2717
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718
;; Size of pushdf using integer instructions is 3+3*memory operand size
2719
;; Pushing using integer instructions is longer except for constants
2720
;; and direct memory references.
2721
;; (assuming that any given constant is pushed only once, but this ought to be
2722
;;  handled elsewhere).
2723
 
2724
(define_insn "*pushxf_nointeger"
2725
  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726
        (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727
  "optimize_size"
2728
{
2729
  /* This insn should be already split before reg-stack.  */
2730
  gcc_unreachable ();
2731
}
2732
  [(set_attr "type" "multi")
2733
   (set_attr "unit" "i387,*,*")
2734
   (set_attr "mode" "XF,SI,SI")])
2735
 
2736
(define_insn "*pushxf_integer"
2737
  [(set (match_operand:XF 0 "push_operand" "=<,<")
2738
        (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2739
  "!optimize_size"
2740
{
2741
  /* This insn should be already split before reg-stack.  */
2742
  gcc_unreachable ();
2743
}
2744
  [(set_attr "type" "multi")
2745
   (set_attr "unit" "i387,*")
2746
   (set_attr "mode" "XF,SI")])
2747
 
2748
(define_split
2749
  [(set (match_operand 0 "push_operand" "")
2750
        (match_operand 1 "general_operand" ""))]
2751
  "reload_completed
2752
   && (GET_MODE (operands[0]) == XFmode
2753
       || GET_MODE (operands[0]) == DFmode)
2754
   && !ANY_FP_REG_P (operands[1])"
2755
  [(const_int 0)]
2756
  "ix86_split_long_move (operands); DONE;")
2757
 
2758
(define_split
2759
  [(set (match_operand:XF 0 "push_operand" "")
2760
        (match_operand:XF 1 "any_fp_register_operand" ""))]
2761
  "!TARGET_64BIT"
2762
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763
   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
 
2766
(define_split
2767
  [(set (match_operand:XF 0 "push_operand" "")
2768
        (match_operand:XF 1 "any_fp_register_operand" ""))]
2769
  "TARGET_64BIT"
2770
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771
   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
 
2774
;; Do not use integer registers when optimizing for size
2775
(define_insn "*movxf_nointeger"
2776
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777
        (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778
  "optimize_size
2779
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780
   && (reload_in_progress || reload_completed
2781
       || GET_CODE (operands[1]) != CONST_DOUBLE
2782
       || memory_operand (operands[0], XFmode))"
2783
{
2784
  switch (which_alternative)
2785
    {
2786
    case 0:
2787
      return output_387_reg_move (insn, operands);
2788
 
2789
    case 1:
2790
      /* There is no non-popping store to memory for XFmode.  So if
2791
         we need one, follow the store with a load.  */
2792
      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793
        return "fstp%z0\t%y0\;fld%z0\t%y0";
2794
      else
2795
        return "fstp%z0\t%y0";
2796
 
2797
    case 2:
2798
      return standard_80387_constant_opcode (operands[1]);
2799
 
2800
    case 3: case 4:
2801
      return "#";
2802
    default:
2803
      gcc_unreachable ();
2804
    }
2805
}
2806
  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807
   (set_attr "mode" "XF,XF,XF,SI,SI")])
2808
 
2809
(define_insn "*movxf_integer"
2810
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2811
        (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2812
  "!optimize_size
2813
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814
   && (reload_in_progress || reload_completed
2815
       || GET_CODE (operands[1]) != CONST_DOUBLE
2816
       || memory_operand (operands[0], XFmode))"
2817
{
2818
  switch (which_alternative)
2819
    {
2820
    case 0:
2821
      return output_387_reg_move (insn, operands);
2822
 
2823
    case 1:
2824
      /* There is no non-popping store to memory for XFmode.  So if
2825
         we need one, follow the store with a load.  */
2826
      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827
        return "fstp%z0\t%y0\;fld%z0\t%y0";
2828
      else
2829
        return "fstp%z0\t%y0";
2830
 
2831
    case 2:
2832
      return standard_80387_constant_opcode (operands[1]);
2833
 
2834
    case 3: case 4:
2835
      return "#";
2836
 
2837
    default:
2838
      gcc_unreachable ();
2839
    }
2840
}
2841
  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842
   (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
 
2844
(define_split
2845
  [(set (match_operand 0 "nonimmediate_operand" "")
2846
        (match_operand 1 "general_operand" ""))]
2847
  "reload_completed
2848
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849
   && GET_MODE (operands[0]) == XFmode
2850
   && ! (ANY_FP_REG_P (operands[0]) ||
2851
         (GET_CODE (operands[0]) == SUBREG
2852
          && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853
   && ! (ANY_FP_REG_P (operands[1]) ||
2854
         (GET_CODE (operands[1]) == SUBREG
2855
          && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856
  [(const_int 0)]
2857
  "ix86_split_long_move (operands); DONE;")
2858
 
2859
(define_split
2860
  [(set (match_operand 0 "register_operand" "")
2861
        (match_operand 1 "memory_operand" ""))]
2862
  "reload_completed
2863
   && GET_CODE (operands[1]) == MEM
2864
   && (GET_MODE (operands[0]) == XFmode
2865
       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866
   && constant_pool_reference_p (operands[1])"
2867
  [(set (match_dup 0) (match_dup 1))]
2868
{
2869
  rtx c = avoid_constant_pool_reference (operands[1]);
2870
  rtx r = operands[0];
2871
 
2872
  if (GET_CODE (r) == SUBREG)
2873
    r = SUBREG_REG (r);
2874
 
2875
  if (SSE_REG_P (r))
2876
    {
2877
      if (!standard_sse_constant_p (c))
2878
        FAIL;
2879
    }
2880
  else if (FP_REG_P (r))
2881
    {
2882
      if (!standard_80387_constant_p (c))
2883
        FAIL;
2884
    }
2885
  else if (MMX_REG_P (r))
2886
    FAIL;
2887
 
2888
  operands[1] = c;
2889
})
2890
 
2891
(define_insn "swapxf"
2892
  [(set (match_operand:XF 0 "register_operand" "+f")
2893
        (match_operand:XF 1 "register_operand" "+f"))
2894
   (set (match_dup 1)
2895
        (match_dup 0))]
2896
  "TARGET_80387"
2897
{
2898
  if (STACK_TOP_P (operands[0]))
2899
    return "fxch\t%1";
2900
  else
2901
    return "fxch\t%0";
2902
}
2903
  [(set_attr "type" "fxch")
2904
   (set_attr "mode" "XF")])
2905
 
2906
(define_expand "movtf"
2907
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908
        (match_operand:TF 1 "nonimmediate_operand" ""))]
2909
  "TARGET_64BIT"
2910
{
2911
  ix86_expand_move (TFmode, operands);
2912
  DONE;
2913
})
2914
 
2915
(define_insn "*movtf_internal"
2916
  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917
        (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2918
  "TARGET_64BIT
2919
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2920
{
2921
  switch (which_alternative)
2922
    {
2923
    case 0:
2924
    case 1:
2925
      return "#";
2926
    case 2:
2927
      if (get_attr_mode (insn) == MODE_V4SF)
2928
        return "xorps\t%0, %0";
2929
      else
2930
        return "pxor\t%0, %0";
2931
    case 3:
2932
    case 4:
2933
      if (get_attr_mode (insn) == MODE_V4SF)
2934
        return "movaps\t{%1, %0|%0, %1}";
2935
      else
2936
        return "movdqa\t{%1, %0|%0, %1}";
2937
    default:
2938
      gcc_unreachable ();
2939
    }
2940
}
2941
  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2942
   (set (attr "mode")
2943
        (cond [(eq_attr "alternative" "2,3")
2944
                 (if_then_else
2945
                   (ne (symbol_ref "optimize_size")
2946
                       (const_int 0))
2947
                   (const_string "V4SF")
2948
                   (const_string "TI"))
2949
               (eq_attr "alternative" "4")
2950
                 (if_then_else
2951
                   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2952
                            (const_int 0))
2953
                        (ne (symbol_ref "optimize_size")
2954
                            (const_int 0)))
2955
                   (const_string "V4SF")
2956
                   (const_string "TI"))]
2957
               (const_string "DI")))])
2958
 
2959
(define_split
2960
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961
        (match_operand:TF 1 "general_operand" ""))]
2962
  "reload_completed && !SSE_REG_P (operands[0])
2963
   && !SSE_REG_P (operands[1])"
2964
  [(const_int 0)]
2965
  "ix86_split_long_move (operands); DONE;")
2966
 
2967
;; Zero extension instructions
2968
 
2969
(define_expand "zero_extendhisi2"
2970
  [(set (match_operand:SI 0 "register_operand" "")
2971
     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972
  ""
2973
{
2974
  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2975
    {
2976
      operands[1] = force_reg (HImode, operands[1]);
2977
      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978
      DONE;
2979
    }
2980
})
2981
 
2982
(define_insn "zero_extendhisi2_and"
2983
  [(set (match_operand:SI 0 "register_operand" "=r")
2984
     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985
   (clobber (reg:CC FLAGS_REG))]
2986
  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987
  "#"
2988
  [(set_attr "type" "alu1")
2989
   (set_attr "mode" "SI")])
2990
 
2991
(define_split
2992
  [(set (match_operand:SI 0 "register_operand" "")
2993
        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994
   (clobber (reg:CC FLAGS_REG))]
2995
  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996
  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997
              (clobber (reg:CC FLAGS_REG))])]
2998
  "")
2999
 
3000
(define_insn "*zero_extendhisi2_movzwl"
3001
  [(set (match_operand:SI 0 "register_operand" "=r")
3002
     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004
  "movz{wl|x}\t{%1, %0|%0, %1}"
3005
  [(set_attr "type" "imovx")
3006
   (set_attr "mode" "SI")])
3007
 
3008
(define_expand "zero_extendqihi2"
3009
  [(parallel
3010
    [(set (match_operand:HI 0 "register_operand" "")
3011
       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012
     (clobber (reg:CC FLAGS_REG))])]
3013
  ""
3014
  "")
3015
 
3016
(define_insn "*zero_extendqihi2_and"
3017
  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019
   (clobber (reg:CC FLAGS_REG))]
3020
  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3021
  "#"
3022
  [(set_attr "type" "alu1")
3023
   (set_attr "mode" "HI")])
3024
 
3025
(define_insn "*zero_extendqihi2_movzbw_and"
3026
  [(set (match_operand:HI 0 "register_operand" "=r,r")
3027
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028
   (clobber (reg:CC FLAGS_REG))]
3029
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3030
  "#"
3031
  [(set_attr "type" "imovx,alu1")
3032
   (set_attr "mode" "HI")])
3033
 
3034
; zero extend to SImode here to avoid partial register stalls
3035
(define_insn "*zero_extendqihi2_movzbl"
3036
  [(set (match_operand:HI 0 "register_operand" "=r")
3037
     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038
  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039
  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040
  [(set_attr "type" "imovx")
3041
   (set_attr "mode" "SI")])
3042
 
3043
;; For the movzbw case strip only the clobber
3044
(define_split
3045
  [(set (match_operand:HI 0 "register_operand" "")
3046
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047
   (clobber (reg:CC FLAGS_REG))]
3048
  "reload_completed
3049
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050
   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051
  [(set (match_operand:HI 0 "register_operand" "")
3052
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
 
3054
;; When source and destination does not overlap, clear destination
3055
;; first and then do the movb
3056
(define_split
3057
  [(set (match_operand:HI 0 "register_operand" "")
3058
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059
   (clobber (reg:CC FLAGS_REG))]
3060
  "reload_completed
3061
   && ANY_QI_REG_P (operands[0])
3062
   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064
  [(set (match_dup 0) (const_int 0))
3065
   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066
  "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
 
3068
;; Rest is handled by single and.
3069
(define_split
3070
  [(set (match_operand:HI 0 "register_operand" "")
3071
        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072
   (clobber (reg:CC FLAGS_REG))]
3073
  "reload_completed
3074
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3075
  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076
              (clobber (reg:CC FLAGS_REG))])]
3077
  "")
3078
 
3079
(define_expand "zero_extendqisi2"
3080
  [(parallel
3081
    [(set (match_operand:SI 0 "register_operand" "")
3082
       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083
     (clobber (reg:CC FLAGS_REG))])]
3084
  ""
3085
  "")
3086
 
3087
(define_insn "*zero_extendqisi2_and"
3088
  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090
   (clobber (reg:CC FLAGS_REG))]
3091
  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092
  "#"
3093
  [(set_attr "type" "alu1")
3094
   (set_attr "mode" "SI")])
3095
 
3096
(define_insn "*zero_extendqisi2_movzbw_and"
3097
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3098
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099
   (clobber (reg:CC FLAGS_REG))]
3100
  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101
  "#"
3102
  [(set_attr "type" "imovx,alu1")
3103
   (set_attr "mode" "SI")])
3104
 
3105
(define_insn "*zero_extendqisi2_movzbw"
3106
  [(set (match_operand:SI 0 "register_operand" "=r")
3107
     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108
  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109
  "movz{bl|x}\t{%1, %0|%0, %1}"
3110
  [(set_attr "type" "imovx")
3111
   (set_attr "mode" "SI")])
3112
 
3113
;; For the movzbl case strip only the clobber
3114
(define_split
3115
  [(set (match_operand:SI 0 "register_operand" "")
3116
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117
   (clobber (reg:CC FLAGS_REG))]
3118
  "reload_completed
3119
   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120
   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121
  [(set (match_dup 0)
3122
        (zero_extend:SI (match_dup 1)))])
3123
 
3124
;; When source and destination does not overlap, clear destination
3125
;; first and then do the movb
3126
(define_split
3127
  [(set (match_operand:SI 0 "register_operand" "")
3128
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129
   (clobber (reg:CC FLAGS_REG))]
3130
  "reload_completed
3131
   && ANY_QI_REG_P (operands[0])
3132
   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133
   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135
  [(set (match_dup 0) (const_int 0))
3136
   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137
  "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
 
3139
;; Rest is handled by single and.
3140
(define_split
3141
  [(set (match_operand:SI 0 "register_operand" "")
3142
        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143
   (clobber (reg:CC FLAGS_REG))]
3144
  "reload_completed
3145
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3146
  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147
              (clobber (reg:CC FLAGS_REG))])]
3148
  "")
3149
 
3150
;; %%% Kill me once multi-word ops are sane.
3151
(define_expand "zero_extendsidi2"
3152
  [(set (match_operand:DI 0 "register_operand" "=r")
3153
     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154
  ""
3155
  "if (!TARGET_64BIT)
3156
     {
3157
       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158
       DONE;
3159
     }
3160
  ")
3161
 
3162
(define_insn "zero_extendsidi2_32"
3163
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165
   (clobber (reg:CC FLAGS_REG))]
3166
  "!TARGET_64BIT"
3167
  "@
3168
   #
3169
   #
3170
   #
3171
   movd\t{%1, %0|%0, %1}
3172
   movd\t{%1, %0|%0, %1}"
3173
  [(set_attr "mode" "SI,SI,SI,DI,TI")
3174
   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
 
3176
(define_insn "zero_extendsidi2_rex64"
3177
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178
     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179
  "TARGET_64BIT"
3180
  "@
3181
   mov\t{%k1, %k0|%k0, %k1}
3182
   #
3183
   movd\t{%1, %0|%0, %1}
3184
   movd\t{%1, %0|%0, %1}"
3185
  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186
   (set_attr "mode" "SI,DI,SI,SI")])
3187
 
3188
(define_split
3189
  [(set (match_operand:DI 0 "memory_operand" "")
3190
     (zero_extend:DI (match_dup 0)))]
3191
  "TARGET_64BIT"
3192
  [(set (match_dup 4) (const_int 0))]
3193
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
 
3195
(define_split
3196
  [(set (match_operand:DI 0 "register_operand" "")
3197
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198
   (clobber (reg:CC FLAGS_REG))]
3199
  "!TARGET_64BIT && reload_completed
3200
   && true_regnum (operands[0]) == true_regnum (operands[1])"
3201
  [(set (match_dup 4) (const_int 0))]
3202
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
 
3204
(define_split
3205
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206
        (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207
   (clobber (reg:CC FLAGS_REG))]
3208
  "!TARGET_64BIT && reload_completed
3209
   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210
  [(set (match_dup 3) (match_dup 1))
3211
   (set (match_dup 4) (const_int 0))]
3212
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
 
3214
(define_insn "zero_extendhidi2"
3215
  [(set (match_operand:DI 0 "register_operand" "=r")
3216
     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217
  "TARGET_64BIT"
3218
  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219
  [(set_attr "type" "imovx")
3220
   (set_attr "mode" "DI")])
3221
 
3222
(define_insn "zero_extendqidi2"
3223
  [(set (match_operand:DI 0 "register_operand" "=r")
3224
     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225
  "TARGET_64BIT"
3226
  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227
  [(set_attr "type" "imovx")
3228
   (set_attr "mode" "DI")])
3229
 
3230
;; Sign extension instructions
3231
 
3232
(define_expand "extendsidi2"
3233
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234
                   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235
              (clobber (reg:CC FLAGS_REG))
3236
              (clobber (match_scratch:SI 2 ""))])]
3237
  ""
3238
{
3239
  if (TARGET_64BIT)
3240
    {
3241
      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242
      DONE;
3243
    }
3244
})
3245
 
3246
(define_insn "*extendsidi2_1"
3247
  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248
        (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249
   (clobber (reg:CC FLAGS_REG))
3250
   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251
  "!TARGET_64BIT"
3252
  "#")
3253
 
3254
(define_insn "extendsidi2_rex64"
3255
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257
  "TARGET_64BIT"
3258
  "@
3259
   {cltq|cdqe}
3260
   movs{lq|x}\t{%1,%0|%0, %1}"
3261
  [(set_attr "type" "imovx")
3262
   (set_attr "mode" "DI")
3263
   (set_attr "prefix_0f" "0")
3264
   (set_attr "modrm" "0,1")])
3265
 
3266
(define_insn "extendhidi2"
3267
  [(set (match_operand:DI 0 "register_operand" "=r")
3268
        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269
  "TARGET_64BIT"
3270
  "movs{wq|x}\t{%1,%0|%0, %1}"
3271
  [(set_attr "type" "imovx")
3272
   (set_attr "mode" "DI")])
3273
 
3274
(define_insn "extendqidi2"
3275
  [(set (match_operand:DI 0 "register_operand" "=r")
3276
        (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277
  "TARGET_64BIT"
3278
  "movs{bq|x}\t{%1,%0|%0, %1}"
3279
   [(set_attr "type" "imovx")
3280
    (set_attr "mode" "DI")])
3281
 
3282
;; Extend to memory case when source register does die.
3283
(define_split
3284
  [(set (match_operand:DI 0 "memory_operand" "")
3285
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286
   (clobber (reg:CC FLAGS_REG))
3287
   (clobber (match_operand:SI 2 "register_operand" ""))]
3288
  "(reload_completed
3289
    && dead_or_set_p (insn, operands[1])
3290
    && !reg_mentioned_p (operands[1], operands[0]))"
3291
  [(set (match_dup 3) (match_dup 1))
3292
   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293
              (clobber (reg:CC FLAGS_REG))])
3294
   (set (match_dup 4) (match_dup 1))]
3295
  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
 
3297
;; Extend to memory case when source register does not die.
3298
(define_split
3299
  [(set (match_operand:DI 0 "memory_operand" "")
3300
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301
   (clobber (reg:CC FLAGS_REG))
3302
   (clobber (match_operand:SI 2 "register_operand" ""))]
3303
  "reload_completed"
3304
  [(const_int 0)]
3305
{
3306
  split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
 
3308
  emit_move_insn (operands[3], operands[1]);
3309
 
3310
  /* Generate a cltd if possible and doing so it profitable.  */
3311
  if (true_regnum (operands[1]) == 0
3312
      && true_regnum (operands[2]) == 1
3313
      && (optimize_size || TARGET_USE_CLTD))
3314
    {
3315
      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316
    }
3317
  else
3318
    {
3319
      emit_move_insn (operands[2], operands[1]);
3320
      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321
    }
3322
  emit_move_insn (operands[4], operands[2]);
3323
  DONE;
3324
})
3325
 
3326
;; Extend to register case.  Optimize case where source and destination
3327
;; registers match and cases where we can use cltd.
3328
(define_split
3329
  [(set (match_operand:DI 0 "register_operand" "")
3330
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331
   (clobber (reg:CC FLAGS_REG))
3332
   (clobber (match_scratch:SI 2 ""))]
3333
  "reload_completed"
3334
  [(const_int 0)]
3335
{
3336
  split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
 
3338
  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339
    emit_move_insn (operands[3], operands[1]);
3340
 
3341
  /* Generate a cltd if possible and doing so it profitable.  */
3342
  if (true_regnum (operands[3]) == 0
3343
      && (optimize_size || TARGET_USE_CLTD))
3344
    {
3345
      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346
      DONE;
3347
    }
3348
 
3349
  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350
    emit_move_insn (operands[4], operands[1]);
3351
 
3352
  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353
  DONE;
3354
})
3355
 
3356
(define_insn "extendhisi2"
3357
  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359
  ""
3360
{
3361
  switch (get_attr_prefix_0f (insn))
3362
    {
3363
    case 0:
3364
      return "{cwtl|cwde}";
3365
    default:
3366
      return "movs{wl|x}\t{%1,%0|%0, %1}";
3367
    }
3368
}
3369
  [(set_attr "type" "imovx")
3370
   (set_attr "mode" "SI")
3371
   (set (attr "prefix_0f")
3372
     ;; movsx is short decodable while cwtl is vector decoded.
3373
     (if_then_else (and (eq_attr "cpu" "!k6")
3374
                        (eq_attr "alternative" "0"))
3375
        (const_string "0")
3376
        (const_string "1")))
3377
   (set (attr "modrm")
3378
     (if_then_else (eq_attr "prefix_0f" "0")
3379
        (const_string "0")
3380
        (const_string "1")))])
3381
 
3382
(define_insn "*extendhisi2_zext"
3383
  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384
        (zero_extend:DI
3385
          (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386
  "TARGET_64BIT"
3387
{
3388
  switch (get_attr_prefix_0f (insn))
3389
    {
3390
    case 0:
3391
      return "{cwtl|cwde}";
3392
    default:
3393
      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394
    }
3395
}
3396
  [(set_attr "type" "imovx")
3397
   (set_attr "mode" "SI")
3398
   (set (attr "prefix_0f")
3399
     ;; movsx is short decodable while cwtl is vector decoded.
3400
     (if_then_else (and (eq_attr "cpu" "!k6")
3401
                        (eq_attr "alternative" "0"))
3402
        (const_string "0")
3403
        (const_string "1")))
3404
   (set (attr "modrm")
3405
     (if_then_else (eq_attr "prefix_0f" "0")
3406
        (const_string "0")
3407
        (const_string "1")))])
3408
 
3409
(define_insn "extendqihi2"
3410
  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412
  ""
3413
{
3414
  switch (get_attr_prefix_0f (insn))
3415
    {
3416
    case 0:
3417
      return "{cbtw|cbw}";
3418
    default:
3419
      return "movs{bw|x}\t{%1,%0|%0, %1}";
3420
    }
3421
}
3422
  [(set_attr "type" "imovx")
3423
   (set_attr "mode" "HI")
3424
   (set (attr "prefix_0f")
3425
     ;; movsx is short decodable while cwtl is vector decoded.
3426
     (if_then_else (and (eq_attr "cpu" "!k6")
3427
                        (eq_attr "alternative" "0"))
3428
        (const_string "0")
3429
        (const_string "1")))
3430
   (set (attr "modrm")
3431
     (if_then_else (eq_attr "prefix_0f" "0")
3432
        (const_string "0")
3433
        (const_string "1")))])
3434
 
3435
(define_insn "extendqisi2"
3436
  [(set (match_operand:SI 0 "register_operand" "=r")
3437
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438
  ""
3439
  "movs{bl|x}\t{%1,%0|%0, %1}"
3440
   [(set_attr "type" "imovx")
3441
    (set_attr "mode" "SI")])
3442
 
3443
(define_insn "*extendqisi2_zext"
3444
  [(set (match_operand:DI 0 "register_operand" "=r")
3445
        (zero_extend:DI
3446
          (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447
  "TARGET_64BIT"
3448
  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449
   [(set_attr "type" "imovx")
3450
    (set_attr "mode" "SI")])
3451
 
3452
;; Conversions between float and double.
3453
 
3454
;; These are all no-ops in the model used for the 80387.  So just
3455
;; emit moves.
3456
 
3457
;; %%% Kill these when call knows how to work out a DFmode push earlier.
3458
(define_insn "*dummy_extendsfdf2"
3459
  [(set (match_operand:DF 0 "push_operand" "=<")
3460
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461
  "0"
3462
  "#")
3463
 
3464
(define_split
3465
  [(set (match_operand:DF 0 "push_operand" "")
3466
        (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467
  "!TARGET_64BIT"
3468
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469
   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
 
3471
(define_split
3472
  [(set (match_operand:DF 0 "push_operand" "")
3473
        (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474
  "TARGET_64BIT"
3475
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476
   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
 
3478
(define_insn "*dummy_extendsfxf2"
3479
  [(set (match_operand:XF 0 "push_operand" "=<")
3480
        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481
  "0"
3482
  "#")
3483
 
3484
(define_split
3485
  [(set (match_operand:XF 0 "push_operand" "")
3486
        (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487
  ""
3488
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489
   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
 
3492
(define_split
3493
  [(set (match_operand:XF 0 "push_operand" "")
3494
        (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495
  "TARGET_64BIT"
3496
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497
   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
 
3500
(define_split
3501
  [(set (match_operand:XF 0 "push_operand" "")
3502
        (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503
  ""
3504
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505
   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
 
3508
(define_split
3509
  [(set (match_operand:XF 0 "push_operand" "")
3510
        (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511
  "TARGET_64BIT"
3512
  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513
   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514
  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
 
3516
(define_expand "extendsfdf2"
3517
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518
        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520
{
3521
  /* ??? Needed for compress_float_constant since all fp constants
3522
     are LEGITIMATE_CONSTANT_P.  */
3523
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524
    {
3525
      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3526
          && standard_80387_constant_p (operands[1]) > 0)
3527
        {
3528
          operands[1] = simplify_const_unary_operation
3529
            (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3530
          emit_move_insn_1 (operands[0], operands[1]);
3531
          DONE;
3532
        }
3533
      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3534
    }
3535
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3536
    operands[1] = force_reg (SFmode, operands[1]);
3537
})
3538
 
3539
(define_insn "*extendsfdf2_mixed"
3540
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3541
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3542
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3543
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3544
{
3545
  switch (which_alternative)
3546
    {
3547
    case 0:
3548
      return output_387_reg_move (insn, operands);
3549
 
3550
    case 1:
3551
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3552
        return "fstp%z0\t%y0";
3553
      else
3554
        return "fst%z0\t%y0";
3555
 
3556
    case 2:
3557
      return "cvtss2sd\t{%1, %0|%0, %1}";
3558
 
3559
    default:
3560
      gcc_unreachable ();
3561
    }
3562
}
3563
  [(set_attr "type" "fmov,fmov,ssecvt")
3564
   (set_attr "mode" "SF,XF,DF")])
3565
 
3566
(define_insn "*extendsfdf2_sse"
3567
  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3568
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3569
  "TARGET_SSE2 && TARGET_SSE_MATH
3570
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571
  "cvtss2sd\t{%1, %0|%0, %1}"
3572
  [(set_attr "type" "ssecvt")
3573
   (set_attr "mode" "DF")])
3574
 
3575
(define_insn "*extendsfdf2_i387"
3576
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3577
        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3578
  "TARGET_80387
3579
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3580
{
3581
  switch (which_alternative)
3582
    {
3583
    case 0:
3584
      return output_387_reg_move (insn, operands);
3585
 
3586
    case 1:
3587
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3588
        return "fstp%z0\t%y0";
3589
      else
3590
        return "fst%z0\t%y0";
3591
 
3592
    default:
3593
      gcc_unreachable ();
3594
    }
3595
}
3596
  [(set_attr "type" "fmov")
3597
   (set_attr "mode" "SF,XF")])
3598
 
3599
(define_expand "extendsfxf2"
3600
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3601
        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3602
  "TARGET_80387"
3603
{
3604
  /* ??? Needed for compress_float_constant since all fp constants
3605
     are LEGITIMATE_CONSTANT_P.  */
3606
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3607
    {
3608
      if (standard_80387_constant_p (operands[1]) > 0)
3609
        {
3610
          operands[1] = simplify_const_unary_operation
3611
            (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3612
          emit_move_insn_1 (operands[0], operands[1]);
3613
          DONE;
3614
        }
3615
      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3616
    }
3617
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3618
    operands[1] = force_reg (SFmode, operands[1]);
3619
})
3620
 
3621
(define_insn "*extendsfxf2_i387"
3622
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3623
        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3624
  "TARGET_80387
3625
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3626
{
3627
  switch (which_alternative)
3628
    {
3629
    case 0:
3630
      return output_387_reg_move (insn, operands);
3631
 
3632
    case 1:
3633
      /* There is no non-popping store to memory for XFmode.  So if
3634
         we need one, follow the store with a load.  */
3635
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636
        return "fstp%z0\t%y0";
3637
      else
3638
        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3639
 
3640
    default:
3641
      gcc_unreachable ();
3642
    }
3643
}
3644
  [(set_attr "type" "fmov")
3645
   (set_attr "mode" "SF,XF")])
3646
 
3647
(define_expand "extenddfxf2"
3648
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3649
        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3650
  "TARGET_80387"
3651
{
3652
  /* ??? Needed for compress_float_constant since all fp constants
3653
     are LEGITIMATE_CONSTANT_P.  */
3654
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3655
    {
3656
      if (standard_80387_constant_p (operands[1]) > 0)
3657
        {
3658
          operands[1] = simplify_const_unary_operation
3659
            (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3660
          emit_move_insn_1 (operands[0], operands[1]);
3661
          DONE;
3662
        }
3663
      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3664
    }
3665
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3666
    operands[1] = force_reg (DFmode, operands[1]);
3667
})
3668
 
3669
(define_insn "*extenddfxf2_i387"
3670
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3671
        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3672
  "TARGET_80387
3673
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3674
{
3675
  switch (which_alternative)
3676
    {
3677
    case 0:
3678
      return output_387_reg_move (insn, operands);
3679
 
3680
    case 1:
3681
      /* There is no non-popping store to memory for XFmode.  So if
3682
         we need one, follow the store with a load.  */
3683
      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684
        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3685
      else
3686
        return "fstp%z0\t%y0";
3687
 
3688
    default:
3689
      gcc_unreachable ();
3690
    }
3691
}
3692
  [(set_attr "type" "fmov")
3693
   (set_attr "mode" "DF,XF")])
3694
 
3695
;; %%% This seems bad bad news.
3696
;; This cannot output into an f-reg because there is no way to be sure
3697
;; of truncating in that case.  Otherwise this is just like a simple move
3698
;; insn.  So we pretend we can output to a reg in order to get better
3699
;; register preferencing, but we really use a stack slot.
3700
 
3701
;; Conversion from DFmode to SFmode.
3702
 
3703
(define_expand "truncdfsf2"
3704
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3705
        (float_truncate:SF
3706
          (match_operand:DF 1 "nonimmediate_operand" "")))]
3707
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3708
{
3709
  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3710
    operands[1] = force_reg (DFmode, operands[1]);
3711
 
3712
  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3713
    ;
3714
  else if (flag_unsafe_math_optimizations)
3715
    ;
3716
  else
3717
    {
3718
      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3719
      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3720
      DONE;
3721
    }
3722
})
3723
 
3724
(define_expand "truncdfsf2_with_temp"
3725
  [(parallel [(set (match_operand:SF 0 "" "")
3726
                   (float_truncate:SF (match_operand:DF 1 "" "")))
3727
              (clobber (match_operand:SF 2 "" ""))])]
3728
  "")
3729
 
3730
(define_insn "*truncdfsf_fast_mixed"
3731
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3732
        (float_truncate:SF
3733
          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3734
  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3735
{
3736
  switch (which_alternative)
3737
    {
3738
    case 0:
3739
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3740
        return "fstp%z0\t%y0";
3741
      else
3742
        return "fst%z0\t%y0";
3743
    case 1:
3744
      return output_387_reg_move (insn, operands);
3745
    case 2:
3746
      return "cvtsd2ss\t{%1, %0|%0, %1}";
3747
    default:
3748
      gcc_unreachable ();
3749
    }
3750
}
3751
  [(set_attr "type" "fmov,fmov,ssecvt")
3752
   (set_attr "mode" "SF")])
3753
 
3754
;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3755
;; because nothing we do here is unsafe.
3756
(define_insn "*truncdfsf_fast_sse"
3757
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3758
        (float_truncate:SF
3759
          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3760
  "TARGET_SSE2 && TARGET_SSE_MATH"
3761
  "cvtsd2ss\t{%1, %0|%0, %1}"
3762
  [(set_attr "type" "ssecvt")
3763
   (set_attr "mode" "SF")])
3764
 
3765
(define_insn "*truncdfsf_fast_i387"
3766
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3767
        (float_truncate:SF
3768
          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3769
  "TARGET_80387 && flag_unsafe_math_optimizations"
3770
  "* return output_387_reg_move (insn, operands);"
3771
  [(set_attr "type" "fmov")
3772
   (set_attr "mode" "SF")])
3773
 
3774
(define_insn "*truncdfsf_mixed"
3775
  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3776
        (float_truncate:SF
3777
          (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3778
   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3779
  "TARGET_MIX_SSE_I387"
3780
{
3781
  switch (which_alternative)
3782
    {
3783
    case 0:
3784
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3785
        return "fstp%z0\t%y0";
3786
      else
3787
        return "fst%z0\t%y0";
3788
    case 1:
3789
      return "#";
3790
    case 2:
3791
      return "cvtsd2ss\t{%1, %0|%0, %1}";
3792
    default:
3793
      gcc_unreachable ();
3794
    }
3795
}
3796
  [(set_attr "type" "fmov,multi,ssecvt")
3797
   (set_attr "unit" "*,i387,*")
3798
   (set_attr "mode" "SF")])
3799
 
3800
(define_insn "*truncdfsf_i387"
3801
  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3802
        (float_truncate:SF
3803
          (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3804
   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3805
  "TARGET_80387"
3806
{
3807
  switch (which_alternative)
3808
    {
3809
    case 0:
3810
      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811
        return "fstp%z0\t%y0";
3812
      else
3813
        return "fst%z0\t%y0";
3814
    case 1:
3815
      return "#";
3816
    default:
3817
      gcc_unreachable ();
3818
    }
3819
}
3820
  [(set_attr "type" "fmov,multi")
3821
   (set_attr "unit" "*,i387")
3822
   (set_attr "mode" "SF")])
3823
 
3824
(define_insn "*truncdfsf2_i387_1"
3825
  [(set (match_operand:SF 0 "memory_operand" "=m")
3826
        (float_truncate:SF
3827
          (match_operand:DF 1 "register_operand" "f")))]
3828
  "TARGET_80387
3829
   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3830
   && !TARGET_MIX_SSE_I387"
3831
{
3832
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833
    return "fstp%z0\t%y0";
3834
  else
3835
    return "fst%z0\t%y0";
3836
}
3837
  [(set_attr "type" "fmov")
3838
   (set_attr "mode" "SF")])
3839
 
3840
(define_split
3841
  [(set (match_operand:SF 0 "register_operand" "")
3842
        (float_truncate:SF
3843
         (match_operand:DF 1 "fp_register_operand" "")))
3844
   (clobber (match_operand 2 "" ""))]
3845
  "reload_completed"
3846
  [(set (match_dup 2) (match_dup 1))
3847
   (set (match_dup 0) (match_dup 2))]
3848
{
3849
  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3850
})
3851
 
3852
;; Conversion from XFmode to SFmode.
3853
 
3854
(define_expand "truncxfsf2"
3855
  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3856
                   (float_truncate:SF
3857
                    (match_operand:XF 1 "register_operand" "")))
3858
              (clobber (match_dup 2))])]
3859
  "TARGET_80387"
3860
{
3861
  if (flag_unsafe_math_optimizations)
3862
    {
3863
      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3864
      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3865
      if (reg != operands[0])
3866
        emit_move_insn (operands[0], reg);
3867
      DONE;
3868
    }
3869
  else
3870
    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3871
})
3872
 
3873
(define_insn "*truncxfsf2_mixed"
3874
  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3875
        (float_truncate:SF
3876
         (match_operand:XF 1 "register_operand" "f,f,f,f")))
3877
   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3878
  "TARGET_MIX_SSE_I387"
3879
{
3880
  gcc_assert (!which_alternative);
3881
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882
    return "fstp%z0\t%y0";
3883
  else
3884
    return "fst%z0\t%y0";
3885
}
3886
  [(set_attr "type" "fmov,multi,multi,multi")
3887
   (set_attr "unit" "*,i387,i387,i387")
3888
   (set_attr "mode" "SF")])
3889
 
3890
(define_insn "truncxfsf2_i387_noop"
3891
  [(set (match_operand:SF 0 "register_operand" "=f")
3892
        (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3893
  "TARGET_80387 && flag_unsafe_math_optimizations"
3894
{
3895
  return output_387_reg_move (insn, operands);
3896
}
3897
  [(set_attr "type" "fmov")
3898
   (set_attr "mode" "SF")])
3899
 
3900
(define_insn "*truncxfsf2_i387"
3901
  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3902
        (float_truncate:SF
3903
         (match_operand:XF 1 "register_operand" "f,f,f")))
3904
   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3905
  "TARGET_80387"
3906
{
3907
  gcc_assert (!which_alternative);
3908
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3909
    return "fstp%z0\t%y0";
3910
   else
3911
     return "fst%z0\t%y0";
3912
}
3913
  [(set_attr "type" "fmov,multi,multi")
3914
   (set_attr "unit" "*,i387,i387")
3915
   (set_attr "mode" "SF")])
3916
 
3917
(define_insn "*truncxfsf2_i387_1"
3918
  [(set (match_operand:SF 0 "memory_operand" "=m")
3919
        (float_truncate:SF
3920
         (match_operand:XF 1 "register_operand" "f")))]
3921
  "TARGET_80387"
3922
{
3923
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924
    return "fstp%z0\t%y0";
3925
  else
3926
    return "fst%z0\t%y0";
3927
}
3928
  [(set_attr "type" "fmov")
3929
   (set_attr "mode" "SF")])
3930
 
3931
(define_split
3932
  [(set (match_operand:SF 0 "register_operand" "")
3933
        (float_truncate:SF
3934
         (match_operand:XF 1 "register_operand" "")))
3935
   (clobber (match_operand:SF 2 "memory_operand" ""))]
3936
  "TARGET_80387 && reload_completed"
3937
  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3938
   (set (match_dup 0) (match_dup 2))]
3939
  "")
3940
 
3941
(define_split
3942
  [(set (match_operand:SF 0 "memory_operand" "")
3943
        (float_truncate:SF
3944
         (match_operand:XF 1 "register_operand" "")))
3945
   (clobber (match_operand:SF 2 "memory_operand" ""))]
3946
  "TARGET_80387"
3947
  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3948
  "")
3949
 
3950
;; Conversion from XFmode to DFmode.
3951
 
3952
(define_expand "truncxfdf2"
3953
  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3954
                   (float_truncate:DF
3955
                    (match_operand:XF 1 "register_operand" "")))
3956
              (clobber (match_dup 2))])]
3957
  "TARGET_80387"
3958
{
3959
  if (flag_unsafe_math_optimizations)
3960
    {
3961
      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3962
      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3963
      if (reg != operands[0])
3964
        emit_move_insn (operands[0], reg);
3965
      DONE;
3966
    }
3967
  else
3968
    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3969
})
3970
 
3971
(define_insn "*truncxfdf2_mixed"
3972
  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3973
        (float_truncate:DF
3974
         (match_operand:XF 1 "register_operand" "f,f,f,f")))
3975
   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3976
  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3977
{
3978
  gcc_assert (!which_alternative);
3979
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3980
    return "fstp%z0\t%y0";
3981
  else
3982
    return "fst%z0\t%y0";
3983
}
3984
  [(set_attr "type" "fmov,multi,multi,multi")
3985
   (set_attr "unit" "*,i387,i387,i387")
3986
   (set_attr "mode" "DF")])
3987
 
3988
(define_insn "truncxfdf2_i387_noop"
3989
  [(set (match_operand:DF 0 "register_operand" "=f")
3990
        (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3991
  "TARGET_80387 && flag_unsafe_math_optimizations"
3992
{
3993
  return output_387_reg_move (insn, operands);
3994
}
3995
  [(set_attr "type" "fmov")
3996
   (set_attr "mode" "DF")])
3997
 
3998
(define_insn "*truncxfdf2_i387"
3999
  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4000
        (float_truncate:DF
4001
         (match_operand:XF 1 "register_operand" "f,f,f")))
4002
   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4003
  "TARGET_80387"
4004
{
4005
  gcc_assert (!which_alternative);
4006
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4007
    return "fstp%z0\t%y0";
4008
  else
4009
    return "fst%z0\t%y0";
4010
}
4011
  [(set_attr "type" "fmov,multi,multi")
4012
   (set_attr "unit" "*,i387,i387")
4013
   (set_attr "mode" "DF")])
4014
 
4015
(define_insn "*truncxfdf2_i387_1"
4016
  [(set (match_operand:DF 0 "memory_operand" "=m")
4017
        (float_truncate:DF
4018
          (match_operand:XF 1 "register_operand" "f")))]
4019
  "TARGET_80387"
4020
{
4021
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022
    return "fstp%z0\t%y0";
4023
  else
4024
    return "fst%z0\t%y0";
4025
}
4026
  [(set_attr "type" "fmov")
4027
   (set_attr "mode" "DF")])
4028
 
4029
(define_split
4030
  [(set (match_operand:DF 0 "register_operand" "")
4031
        (float_truncate:DF
4032
         (match_operand:XF 1 "register_operand" "")))
4033
   (clobber (match_operand:DF 2 "memory_operand" ""))]
4034
  "TARGET_80387 && reload_completed"
4035
  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4036
   (set (match_dup 0) (match_dup 2))]
4037
  "")
4038
 
4039
(define_split
4040
  [(set (match_operand:DF 0 "memory_operand" "")
4041
        (float_truncate:DF
4042
         (match_operand:XF 1 "register_operand" "")))
4043
   (clobber (match_operand:DF 2 "memory_operand" ""))]
4044
  "TARGET_80387"
4045
  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4046
  "")
4047
 
4048
;; Signed conversion to DImode.
4049
 
4050
(define_expand "fix_truncxfdi2"
4051
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052
                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4053
              (clobber (reg:CC FLAGS_REG))])]
4054
  "TARGET_80387"
4055
{
4056
  if (TARGET_FISTTP)
4057
   {
4058
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4059
     DONE;
4060
   }
4061
})
4062
 
4063
(define_expand "fix_truncdi2"
4064
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4065
                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4066
              (clobber (reg:CC FLAGS_REG))])]
4067
  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))"
4068
{
4069
  if (TARGET_FISTTP
4070
      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4071
   {
4072
     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4073
     DONE;
4074
   }
4075
  if (TARGET_64BIT && SSE_FLOAT_MODE_P (mode))
4076
   {
4077
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4078
     emit_insn (gen_fix_truncdi_sse (out, operands[1]));
4079
     if (out != operands[0])
4080
        emit_move_insn (operands[0], out);
4081
     DONE;
4082
   }
4083
})
4084
 
4085
;; Signed conversion to SImode.
4086
 
4087
(define_expand "fix_truncxfsi2"
4088
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089
                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4090
              (clobber (reg:CC FLAGS_REG))])]
4091
  "TARGET_80387"
4092
{
4093
  if (TARGET_FISTTP)
4094
   {
4095
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4096
     DONE;
4097
   }
4098
})
4099
 
4100
(define_expand "fix_truncsi2"
4101
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4102
                   (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4103
              (clobber (reg:CC FLAGS_REG))])]
4104
  "TARGET_80387 || SSE_FLOAT_MODE_P (mode)"
4105
{
4106
  if (TARGET_FISTTP
4107
      && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
4108
   {
4109
     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4110
     DONE;
4111
   }
4112
  if (SSE_FLOAT_MODE_P (mode))
4113
   {
4114
     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4115
     emit_insn (gen_fix_truncsi_sse (out, operands[1]));
4116
     if (out != operands[0])
4117
        emit_move_insn (operands[0], out);
4118
     DONE;
4119
   }
4120
})
4121
 
4122
;; Signed conversion to HImode.
4123
 
4124
(define_expand "fix_trunchi2"
4125
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4126
                   (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4127
              (clobber (reg:CC FLAGS_REG))])]
4128
  "TARGET_80387
4129
   && !(SSE_FLOAT_MODE_P (mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4130
{
4131
  if (TARGET_FISTTP)
4132
   {
4133
     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4134
     DONE;
4135
   }
4136
})
4137
 
4138
;; When SSE is available, it is always faster to use it!
4139
(define_insn "fix_truncsfdi_sse"
4140
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4141
        (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4142
  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143
  "cvttss2si{q}\t{%1, %0|%0, %1}"
4144
  [(set_attr "type" "sseicvt")
4145
   (set_attr "mode" "SF")
4146
   (set_attr "athlon_decode" "double,vector")])
4147
 
4148
(define_insn "fix_truncdfdi_sse"
4149
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4150
        (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4151
  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4152
  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4153
  [(set_attr "type" "sseicvt")
4154
   (set_attr "mode" "DF")
4155
   (set_attr "athlon_decode" "double,vector")])
4156
 
4157
(define_insn "fix_truncsfsi_sse"
4158
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4159
        (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4160
  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4161
  "cvttss2si\t{%1, %0|%0, %1}"
4162
  [(set_attr "type" "sseicvt")
4163
   (set_attr "mode" "DF")
4164
   (set_attr "athlon_decode" "double,vector")])
4165
 
4166
(define_insn "fix_truncdfsi_sse"
4167
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4168
        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169
  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4170
  "cvttsd2si\t{%1, %0|%0, %1}"
4171
  [(set_attr "type" "sseicvt")
4172
   (set_attr "mode" "DF")
4173
   (set_attr "athlon_decode" "double,vector")])
4174
 
4175
;; Avoid vector decoded forms of the instruction.
4176
(define_peephole2
4177
  [(match_scratch:DF 2 "Y")
4178
   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4179
        (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4180
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4181
  [(set (match_dup 2) (match_dup 1))
4182
   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4183
  "")
4184
 
4185
(define_peephole2
4186
  [(match_scratch:SF 2 "x")
4187
   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4188
        (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4189
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4190
  [(set (match_dup 2) (match_dup 1))
4191
   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4192
  "")
4193
 
4194
(define_insn_and_split "fix_trunc_fisttp_i387_1"
4195
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4196
        (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4197
  "TARGET_FISTTP
4198
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4199
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200
         && (TARGET_64BIT || mode != DImode))
4201
        && TARGET_SSE_MATH)
4202
   && !(reload_completed || reload_in_progress)"
4203
  "#"
4204
  "&& 1"
4205
  [(const_int 0)]
4206
{
4207
  if (memory_operand (operands[0], VOIDmode))
4208
    emit_insn (gen_fix_trunc_i387_fisttp (operands[0], operands[1]));
4209
  else
4210
    {
4211
      operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
4212
      emit_insn (gen_fix_trunc_i387_fisttp_with_temp (operands[0],
4213
                                                            operands[1],
4214
                                                            operands[2]));
4215
    }
4216
  DONE;
4217
}
4218
  [(set_attr "type" "fisttp")
4219
   (set_attr "mode" "")])
4220
 
4221
(define_insn "fix_trunc_i387_fisttp"
4222
  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4223
        (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4224
   (clobber (match_scratch:XF 2 "=&1f"))]
4225
  "TARGET_FISTTP
4226
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4227
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4228
         && (TARGET_64BIT || mode != DImode))
4229
        && TARGET_SSE_MATH)"
4230
  "* return output_fix_trunc (insn, operands, 1);"
4231
  [(set_attr "type" "fisttp")
4232
   (set_attr "mode" "")])
4233
 
4234
(define_insn "fix_trunc_i387_fisttp_with_temp"
4235
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4236
        (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4237
   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4238
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4239
  "TARGET_FISTTP
4240
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4241
   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4242
        && (TARGET_64BIT || mode != DImode))
4243
        && TARGET_SSE_MATH)"
4244
  "#"
4245
  [(set_attr "type" "fisttp")
4246
   (set_attr "mode" "")])
4247
 
4248
(define_split
4249
  [(set (match_operand:X87MODEI 0 "register_operand" "")
4250
        (fix:X87MODEI (match_operand 1 "register_operand" "")))
4251
   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4252
   (clobber (match_scratch 3 ""))]
4253
  "reload_completed"
4254
  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4255
              (clobber (match_dup 3))])
4256
   (set (match_dup 0) (match_dup 2))]
4257
  "")
4258
 
4259
(define_split
4260
  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4261
        (fix:X87MODEI (match_operand 1 "register_operand" "")))
4262
   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4263
   (clobber (match_scratch 3 ""))]
4264
  "reload_completed"
4265
  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4266
              (clobber (match_dup 3))])]
4267
  "")
4268
 
4269
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4270
;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4271
;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4272
;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4273
;; function in i386.c.
4274
(define_insn_and_split "*fix_trunc_i387_1"
4275
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4276
        (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4277
   (clobber (reg:CC FLAGS_REG))]
4278
  "TARGET_80387 && !TARGET_FISTTP
4279
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4280
   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4281
         && (TARGET_64BIT || mode != DImode))
4282
   && !(reload_completed || reload_in_progress)"
4283
  "#"
4284
  "&& 1"
4285
  [(const_int 0)]
4286
{
4287
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4288
 
4289
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4290
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4291
  if (memory_operand (operands[0], VOIDmode))
4292
    emit_insn (gen_fix_trunc_i387 (operands[0], operands[1],
4293
                                         operands[2], operands[3]));
4294
  else
4295
    {
4296
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
4297
      emit_insn (gen_fix_trunc_i387_with_temp (operands[0], operands[1],
4298
                                                     operands[2], operands[3],
4299
                                                     operands[4]));
4300
    }
4301
  DONE;
4302
}
4303
  [(set_attr "type" "fistp")
4304
   (set_attr "i387_cw" "trunc")
4305
   (set_attr "mode" "")])
4306
 
4307
(define_insn "fix_truncdi_i387"
4308
  [(set (match_operand:DI 0 "memory_operand" "=m")
4309
        (fix:DI (match_operand 1 "register_operand" "f")))
4310
   (use (match_operand:HI 2 "memory_operand" "m"))
4311
   (use (match_operand:HI 3 "memory_operand" "m"))
4312
   (clobber (match_scratch:XF 4 "=&1f"))]
4313
  "TARGET_80387 && !TARGET_FISTTP
4314
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4315
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4316
  "* return output_fix_trunc (insn, operands, 0);"
4317
  [(set_attr "type" "fistp")
4318
   (set_attr "i387_cw" "trunc")
4319
   (set_attr "mode" "DI")])
4320
 
4321
(define_insn "fix_truncdi_i387_with_temp"
4322
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4323
        (fix:DI (match_operand 1 "register_operand" "f,f")))
4324
   (use (match_operand:HI 2 "memory_operand" "m,m"))
4325
   (use (match_operand:HI 3 "memory_operand" "m,m"))
4326
   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4327
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4328
  "TARGET_80387 && !TARGET_FISTTP
4329
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4330
   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4331
  "#"
4332
  [(set_attr "type" "fistp")
4333
   (set_attr "i387_cw" "trunc")
4334
   (set_attr "mode" "DI")])
4335
 
4336
(define_split
4337
  [(set (match_operand:DI 0 "register_operand" "")
4338
        (fix:DI (match_operand 1 "register_operand" "")))
4339
   (use (match_operand:HI 2 "memory_operand" ""))
4340
   (use (match_operand:HI 3 "memory_operand" ""))
4341
   (clobber (match_operand:DI 4 "memory_operand" ""))
4342
   (clobber (match_scratch 5 ""))]
4343
  "reload_completed"
4344
  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4345
              (use (match_dup 2))
4346
              (use (match_dup 3))
4347
              (clobber (match_dup 5))])
4348
   (set (match_dup 0) (match_dup 4))]
4349
  "")
4350
 
4351
(define_split
4352
  [(set (match_operand:DI 0 "memory_operand" "")
4353
        (fix:DI (match_operand 1 "register_operand" "")))
4354
   (use (match_operand:HI 2 "memory_operand" ""))
4355
   (use (match_operand:HI 3 "memory_operand" ""))
4356
   (clobber (match_operand:DI 4 "memory_operand" ""))
4357
   (clobber (match_scratch 5 ""))]
4358
  "reload_completed"
4359
  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4360
              (use (match_dup 2))
4361
              (use (match_dup 3))
4362
              (clobber (match_dup 5))])]
4363
  "")
4364
 
4365
(define_insn "fix_trunc_i387"
4366
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4367
        (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4368
   (use (match_operand:HI 2 "memory_operand" "m"))
4369
   (use (match_operand:HI 3 "memory_operand" "m"))]
4370
  "TARGET_80387 && !TARGET_FISTTP
4371
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4372
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373
  "* return output_fix_trunc (insn, operands, 0);"
4374
  [(set_attr "type" "fistp")
4375
   (set_attr "i387_cw" "trunc")
4376
   (set_attr "mode" "")])
4377
 
4378
(define_insn "fix_trunc_i387_with_temp"
4379
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4380
        (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4381
   (use (match_operand:HI 2 "memory_operand" "m,m"))
4382
   (use (match_operand:HI 3 "memory_operand" "m,m"))
4383
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4384
  "TARGET_80387 && !TARGET_FISTTP
4385
   && FLOAT_MODE_P (GET_MODE (operands[1]))
4386
   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387
  "#"
4388
  [(set_attr "type" "fistp")
4389
   (set_attr "i387_cw" "trunc")
4390
   (set_attr "mode" "")])
4391
 
4392
(define_split
4393
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4394
        (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4395
   (use (match_operand:HI 2 "memory_operand" ""))
4396
   (use (match_operand:HI 3 "memory_operand" ""))
4397
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4398
  "reload_completed"
4399
  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4400
              (use (match_dup 2))
4401
              (use (match_dup 3))])
4402
   (set (match_dup 0) (match_dup 4))]
4403
  "")
4404
 
4405
(define_split
4406
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4407
        (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4408
   (use (match_operand:HI 2 "memory_operand" ""))
4409
   (use (match_operand:HI 3 "memory_operand" ""))
4410
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4411
  "reload_completed"
4412
  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4413
              (use (match_dup 2))
4414
              (use (match_dup 3))])]
4415
  "")
4416
 
4417
(define_insn "x86_fnstcw_1"
4418
  [(set (match_operand:HI 0 "memory_operand" "=m")
4419
        (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4420
  "TARGET_80387"
4421
  "fnstcw\t%0"
4422
  [(set_attr "length" "2")
4423
   (set_attr "mode" "HI")
4424
   (set_attr "unit" "i387")])
4425
 
4426
(define_insn "x86_fldcw_1"
4427
  [(set (reg:HI FPSR_REG)
4428
        (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4429
  "TARGET_80387"
4430
  "fldcw\t%0"
4431
  [(set_attr "length" "2")
4432
   (set_attr "mode" "HI")
4433
   (set_attr "unit" "i387")
4434
   (set_attr "athlon_decode" "vector")])
4435
 
4436
;; Conversion between fixed point and floating point.
4437
 
4438
;; Even though we only accept memory inputs, the backend _really_
4439
;; wants to be able to do this between registers.
4440
 
4441
(define_expand "floathisf2"
4442
  [(set (match_operand:SF 0 "register_operand" "")
4443
        (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4444
  "TARGET_80387 || TARGET_SSE_MATH"
4445
{
4446
  if (TARGET_SSE_MATH)
4447
    {
4448
      emit_insn (gen_floatsisf2 (operands[0],
4449
                                 convert_to_mode (SImode, operands[1], 0)));
4450
      DONE;
4451
    }
4452
})
4453
 
4454
(define_insn "*floathisf2_i387"
4455
  [(set (match_operand:SF 0 "register_operand" "=f,f")
4456
        (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4457
  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4458
  "@
4459
   fild%z1\t%1
4460
   #"
4461
  [(set_attr "type" "fmov,multi")
4462
   (set_attr "mode" "SF")
4463
   (set_attr "unit" "*,i387")
4464
   (set_attr "fp_int_src" "true")])
4465
 
4466
(define_expand "floatsisf2"
4467
  [(set (match_operand:SF 0 "register_operand" "")
4468
        (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4469
  "TARGET_80387 || TARGET_SSE_MATH"
4470
  "")
4471
 
4472
(define_insn "*floatsisf2_mixed"
4473
  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4474
        (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4475
  "TARGET_MIX_SSE_I387"
4476
  "@
4477
   fild%z1\t%1
4478
   #
4479
   cvtsi2ss\t{%1, %0|%0, %1}
4480
   cvtsi2ss\t{%1, %0|%0, %1}"
4481
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4482
   (set_attr "mode" "SF")
4483
   (set_attr "unit" "*,i387,*,*")
4484
   (set_attr "athlon_decode" "*,*,vector,double")
4485
   (set_attr "fp_int_src" "true")])
4486
 
4487
(define_insn "*floatsisf2_sse"
4488
  [(set (match_operand:SF 0 "register_operand" "=x,x")
4489
        (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4490
  "TARGET_SSE_MATH"
4491
  "cvtsi2ss\t{%1, %0|%0, %1}"
4492
  [(set_attr "type" "sseicvt")
4493
   (set_attr "mode" "SF")
4494
   (set_attr "athlon_decode" "vector,double")
4495
   (set_attr "fp_int_src" "true")])
4496
 
4497
(define_insn "*floatsisf2_i387"
4498
  [(set (match_operand:SF 0 "register_operand" "=f,f")
4499
        (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4500
  "TARGET_80387"
4501
  "@
4502
   fild%z1\t%1
4503
   #"
4504
  [(set_attr "type" "fmov,multi")
4505
   (set_attr "mode" "SF")
4506
   (set_attr "unit" "*,i387")
4507
   (set_attr "fp_int_src" "true")])
4508
 
4509
(define_expand "floatdisf2"
4510
  [(set (match_operand:SF 0 "register_operand" "")
4511
        (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4512
  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4513
  "")
4514
 
4515
(define_insn "*floatdisf2_mixed"
4516
  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4517
        (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4518
  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4519
  "@
4520
   fild%z1\t%1
4521
   #
4522
   cvtsi2ss{q}\t{%1, %0|%0, %1}
4523
   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4524
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4525
   (set_attr "mode" "SF")
4526
   (set_attr "unit" "*,i387,*,*")
4527
   (set_attr "athlon_decode" "*,*,vector,double")
4528
   (set_attr "fp_int_src" "true")])
4529
 
4530
(define_insn "*floatdisf2_sse"
4531
  [(set (match_operand:SF 0 "register_operand" "=x,x")
4532
        (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4533
  "TARGET_64BIT && TARGET_SSE_MATH"
4534
  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4535
  [(set_attr "type" "sseicvt")
4536
   (set_attr "mode" "SF")
4537
   (set_attr "athlon_decode" "vector,double")
4538
   (set_attr "fp_int_src" "true")])
4539
 
4540
(define_insn "*floatdisf2_i387"
4541
  [(set (match_operand:SF 0 "register_operand" "=f,f")
4542
        (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4543
  "TARGET_80387"
4544
  "@
4545
   fild%z1\t%1
4546
   #"
4547
  [(set_attr "type" "fmov,multi")
4548
   (set_attr "mode" "SF")
4549
   (set_attr "unit" "*,i387")
4550
   (set_attr "fp_int_src" "true")])
4551
 
4552
(define_expand "floathidf2"
4553
  [(set (match_operand:DF 0 "register_operand" "")
4554
        (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4555
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4556
{
4557
  if (TARGET_SSE2 && TARGET_SSE_MATH)
4558
    {
4559
      emit_insn (gen_floatsidf2 (operands[0],
4560
                                 convert_to_mode (SImode, operands[1], 0)));
4561
      DONE;
4562
    }
4563
})
4564
 
4565
(define_insn "*floathidf2_i387"
4566
  [(set (match_operand:DF 0 "register_operand" "=f,f")
4567
        (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4568
  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4569
  "@
4570
   fild%z1\t%1
4571
   #"
4572
  [(set_attr "type" "fmov,multi")
4573
   (set_attr "mode" "DF")
4574
   (set_attr "unit" "*,i387")
4575
   (set_attr "fp_int_src" "true")])
4576
 
4577
(define_expand "floatsidf2"
4578
  [(set (match_operand:DF 0 "register_operand" "")
4579
        (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581
  "")
4582
 
4583
(define_insn "*floatsidf2_mixed"
4584
  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4585
        (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586
  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587
  "@
4588
   fild%z1\t%1
4589
   #
4590
   cvtsi2sd\t{%1, %0|%0, %1}
4591
   cvtsi2sd\t{%1, %0|%0, %1}"
4592
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593
   (set_attr "mode" "DF")
4594
   (set_attr "unit" "*,i387,*,*")
4595
   (set_attr "athlon_decode" "*,*,double,direct")
4596
   (set_attr "fp_int_src" "true")])
4597
 
4598
(define_insn "*floatsidf2_sse"
4599
  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4600
        (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4601
  "TARGET_SSE2 && TARGET_SSE_MATH"
4602
  "cvtsi2sd\t{%1, %0|%0, %1}"
4603
  [(set_attr "type" "sseicvt")
4604
   (set_attr "mode" "DF")
4605
   (set_attr "athlon_decode" "double,direct")
4606
   (set_attr "fp_int_src" "true")])
4607
 
4608
(define_insn "*floatsidf2_i387"
4609
  [(set (match_operand:DF 0 "register_operand" "=f,f")
4610
        (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4611
  "TARGET_80387"
4612
  "@
4613
   fild%z1\t%1
4614
   #"
4615
  [(set_attr "type" "fmov,multi")
4616
   (set_attr "mode" "DF")
4617
   (set_attr "unit" "*,i387")
4618
   (set_attr "fp_int_src" "true")])
4619
 
4620
(define_expand "floatdidf2"
4621
  [(set (match_operand:DF 0 "register_operand" "")
4622
        (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4623
  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4624
  "")
4625
 
4626
(define_insn "*floatdidf2_mixed"
4627
  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4628
        (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4629
  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4630
  "@
4631
   fild%z1\t%1
4632
   #
4633
   cvtsi2sd{q}\t{%1, %0|%0, %1}
4634
   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4635
  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4636
   (set_attr "mode" "DF")
4637
   (set_attr "unit" "*,i387,*,*")
4638
   (set_attr "athlon_decode" "*,*,double,direct")
4639
   (set_attr "fp_int_src" "true")])
4640
 
4641
(define_insn "*floatdidf2_sse"
4642
  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4643
        (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4644
  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4645
  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4646
  [(set_attr "type" "sseicvt")
4647
   (set_attr "mode" "DF")
4648
   (set_attr "athlon_decode" "double,direct")
4649
   (set_attr "fp_int_src" "true")])
4650
 
4651
(define_insn "*floatdidf2_i387"
4652
  [(set (match_operand:DF 0 "register_operand" "=f,f")
4653
        (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4654
  "TARGET_80387"
4655
  "@
4656
   fild%z1\t%1
4657
   #"
4658
  [(set_attr "type" "fmov,multi")
4659
   (set_attr "mode" "DF")
4660
   (set_attr "unit" "*,i387")
4661
   (set_attr "fp_int_src" "true")])
4662
 
4663
(define_insn "floathixf2"
4664
  [(set (match_operand:XF 0 "register_operand" "=f,f")
4665
        (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4666
  "TARGET_80387"
4667
  "@
4668
   fild%z1\t%1
4669
   #"
4670
  [(set_attr "type" "fmov,multi")
4671
   (set_attr "mode" "XF")
4672
   (set_attr "unit" "*,i387")
4673
   (set_attr "fp_int_src" "true")])
4674
 
4675
(define_insn "floatsixf2"
4676
  [(set (match_operand:XF 0 "register_operand" "=f,f")
4677
        (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4678
  "TARGET_80387"
4679
  "@
4680
   fild%z1\t%1
4681
   #"
4682
  [(set_attr "type" "fmov,multi")
4683
   (set_attr "mode" "XF")
4684
   (set_attr "unit" "*,i387")
4685
   (set_attr "fp_int_src" "true")])
4686
 
4687
(define_insn "floatdixf2"
4688
  [(set (match_operand:XF 0 "register_operand" "=f,f")
4689
        (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4690
  "TARGET_80387"
4691
  "@
4692
   fild%z1\t%1
4693
   #"
4694
  [(set_attr "type" "fmov,multi")
4695
   (set_attr "mode" "XF")
4696
   (set_attr "unit" "*,i387")
4697
   (set_attr "fp_int_src" "true")])
4698
 
4699
;; %%% Kill these when reload knows how to do it.
4700
(define_split
4701
  [(set (match_operand 0 "fp_register_operand" "")
4702
        (float (match_operand 1 "register_operand" "")))]
4703
  "reload_completed
4704
   && TARGET_80387
4705
   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4706
  [(const_int 0)]
4707
{
4708
  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4709
  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4710
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4711
  ix86_free_from_memory (GET_MODE (operands[1]));
4712
  DONE;
4713
})
4714
 
4715
(define_expand "floatunssisf2"
4716
  [(use (match_operand:SF 0 "register_operand" ""))
4717
   (use (match_operand:SI 1 "register_operand" ""))]
4718
  "!TARGET_64BIT && TARGET_SSE_MATH"
4719
  "x86_emit_floatuns (operands); DONE;")
4720
 
4721
(define_expand "floatunsdisf2"
4722
  [(use (match_operand:SF 0 "register_operand" ""))
4723
   (use (match_operand:DI 1 "register_operand" ""))]
4724
  "TARGET_64BIT && TARGET_SSE_MATH"
4725
  "x86_emit_floatuns (operands); DONE;")
4726
 
4727
(define_expand "floatunsdidf2"
4728
  [(use (match_operand:DF 0 "register_operand" ""))
4729
   (use (match_operand:DI 1 "register_operand" ""))]
4730
  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731
  "x86_emit_floatuns (operands); DONE;")
4732
 
4733
;; SSE extract/set expanders
4734
 
4735
 
4736
;; Add instructions
4737
 
4738
;; %%% splits for addditi3
4739
 
4740
(define_expand "addti3"
4741
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4742
        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4743
                 (match_operand:TI 2 "x86_64_general_operand" "")))
4744
   (clobber (reg:CC FLAGS_REG))]
4745
  "TARGET_64BIT"
4746
  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4747
 
4748
(define_insn "*addti3_1"
4749
  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4750
        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4751
                 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4752
   (clobber (reg:CC FLAGS_REG))]
4753
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4754
  "#")
4755
 
4756
(define_split
4757
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758
        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759
                 (match_operand:TI 2 "x86_64_general_operand" "")))
4760
   (clobber (reg:CC FLAGS_REG))]
4761
  "TARGET_64BIT && reload_completed"
4762
  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4763
                                          UNSPEC_ADD_CARRY))
4764
              (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4765
   (parallel [(set (match_dup 3)
4766
                   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4767
                                     (match_dup 4))
4768
                            (match_dup 5)))
4769
              (clobber (reg:CC FLAGS_REG))])]
4770
  "split_ti (operands+0, 1, operands+0, operands+3);
4771
   split_ti (operands+1, 1, operands+1, operands+4);
4772
   split_ti (operands+2, 1, operands+2, operands+5);")
4773
 
4774
;; %%% splits for addsidi3
4775
;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4776
;       (plus:DI (match_operand:DI 1 "general_operand" "")
4777
;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4778
 
4779
(define_expand "adddi3"
4780
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4781
        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4782
                 (match_operand:DI 2 "x86_64_general_operand" "")))
4783
   (clobber (reg:CC FLAGS_REG))]
4784
  ""
4785
  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4786
 
4787
(define_insn "*adddi3_1"
4788
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4789
        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4790
                 (match_operand:DI 2 "general_operand" "roiF,riF")))
4791
   (clobber (reg:CC FLAGS_REG))]
4792
  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4793
  "#")
4794
 
4795
(define_split
4796
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797
        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798
                 (match_operand:DI 2 "general_operand" "")))
4799
   (clobber (reg:CC FLAGS_REG))]
4800
  "!TARGET_64BIT && reload_completed"
4801
  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4802
                                          UNSPEC_ADD_CARRY))
4803
              (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4804
   (parallel [(set (match_dup 3)
4805
                   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4806
                                     (match_dup 4))
4807
                            (match_dup 5)))
4808
              (clobber (reg:CC FLAGS_REG))])]
4809
  "split_di (operands+0, 1, operands+0, operands+3);
4810
   split_di (operands+1, 1, operands+1, operands+4);
4811
   split_di (operands+2, 1, operands+2, operands+5);")
4812
 
4813
(define_insn "adddi3_carry_rex64"
4814
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4815
          (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4816
                            (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4817
                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4818
   (clobber (reg:CC FLAGS_REG))]
4819
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4820
  "adc{q}\t{%2, %0|%0, %2}"
4821
  [(set_attr "type" "alu")
4822
   (set_attr "pent_pair" "pu")
4823
   (set_attr "mode" "DI")])
4824
 
4825
(define_insn "*adddi3_cc_rex64"
4826
  [(set (reg:CC FLAGS_REG)
4827
        (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828
                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4829
                   UNSPEC_ADD_CARRY))
4830
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831
        (plus:DI (match_dup 1) (match_dup 2)))]
4832
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4833
  "add{q}\t{%2, %0|%0, %2}"
4834
  [(set_attr "type" "alu")
4835
   (set_attr "mode" "DI")])
4836
 
4837
(define_insn "addqi3_carry"
4838
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4839
          (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4840
                            (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4841
                   (match_operand:QI 2 "general_operand" "qi,qm")))
4842
   (clobber (reg:CC FLAGS_REG))]
4843
  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4844
  "adc{b}\t{%2, %0|%0, %2}"
4845
  [(set_attr "type" "alu")
4846
   (set_attr "pent_pair" "pu")
4847
   (set_attr "mode" "QI")])
4848
 
4849
(define_insn "addhi3_carry"
4850
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4851
          (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4852
                            (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4853
                   (match_operand:HI 2 "general_operand" "ri,rm")))
4854
   (clobber (reg:CC FLAGS_REG))]
4855
  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4856
  "adc{w}\t{%2, %0|%0, %2}"
4857
  [(set_attr "type" "alu")
4858
   (set_attr "pent_pair" "pu")
4859
   (set_attr "mode" "HI")])
4860
 
4861
(define_insn "addsi3_carry"
4862
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4863
          (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4864
                            (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4865
                   (match_operand:SI 2 "general_operand" "ri,rm")))
4866
   (clobber (reg:CC FLAGS_REG))]
4867
  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4868
  "adc{l}\t{%2, %0|%0, %2}"
4869
  [(set_attr "type" "alu")
4870
   (set_attr "pent_pair" "pu")
4871
   (set_attr "mode" "SI")])
4872
 
4873
(define_insn "*addsi3_carry_zext"
4874
  [(set (match_operand:DI 0 "register_operand" "=r")
4875
          (zero_extend:DI
4876
            (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4877
                              (match_operand:SI 1 "nonimmediate_operand" "%0"))
4878
                     (match_operand:SI 2 "general_operand" "rim"))))
4879
   (clobber (reg:CC FLAGS_REG))]
4880
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4881
  "adc{l}\t{%2, %k0|%k0, %2}"
4882
  [(set_attr "type" "alu")
4883
   (set_attr "pent_pair" "pu")
4884
   (set_attr "mode" "SI")])
4885
 
4886
(define_insn "*addsi3_cc"
4887
  [(set (reg:CC FLAGS_REG)
4888
        (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4889
                    (match_operand:SI 2 "general_operand" "ri,rm")]
4890
                   UNSPEC_ADD_CARRY))
4891
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4892
        (plus:SI (match_dup 1) (match_dup 2)))]
4893
  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4894
  "add{l}\t{%2, %0|%0, %2}"
4895
  [(set_attr "type" "alu")
4896
   (set_attr "mode" "SI")])
4897
 
4898
(define_insn "addqi3_cc"
4899
  [(set (reg:CC FLAGS_REG)
4900
        (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4901
                    (match_operand:QI 2 "general_operand" "qi,qm")]
4902
                   UNSPEC_ADD_CARRY))
4903
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4904
        (plus:QI (match_dup 1) (match_dup 2)))]
4905
  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4906
  "add{b}\t{%2, %0|%0, %2}"
4907
  [(set_attr "type" "alu")
4908
   (set_attr "mode" "QI")])
4909
 
4910
(define_expand "addsi3"
4911
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4912
                   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4913
                            (match_operand:SI 2 "general_operand" "")))
4914
              (clobber (reg:CC FLAGS_REG))])]
4915
  ""
4916
  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4917
 
4918
(define_insn "*lea_1"
4919
  [(set (match_operand:SI 0 "register_operand" "=r")
4920
        (match_operand:SI 1 "no_seg_address_operand" "p"))]
4921
  "!TARGET_64BIT"
4922
  "lea{l}\t{%a1, %0|%0, %a1}"
4923
  [(set_attr "type" "lea")
4924
   (set_attr "mode" "SI")])
4925
 
4926
(define_insn "*lea_1_rex64"
4927
  [(set (match_operand:SI 0 "register_operand" "=r")
4928
        (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4929
  "TARGET_64BIT"
4930
  "lea{l}\t{%a1, %0|%0, %a1}"
4931
  [(set_attr "type" "lea")
4932
   (set_attr "mode" "SI")])
4933
 
4934
(define_insn "*lea_1_zext"
4935
  [(set (match_operand:DI 0 "register_operand" "=r")
4936
        (zero_extend:DI
4937
         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4938
  "TARGET_64BIT"
4939
  "lea{l}\t{%a1, %k0|%k0, %a1}"
4940
  [(set_attr "type" "lea")
4941
   (set_attr "mode" "SI")])
4942
 
4943
(define_insn "*lea_2_rex64"
4944
  [(set (match_operand:DI 0 "register_operand" "=r")
4945
        (match_operand:DI 1 "no_seg_address_operand" "p"))]
4946
  "TARGET_64BIT"
4947
  "lea{q}\t{%a1, %0|%0, %a1}"
4948
  [(set_attr "type" "lea")
4949
   (set_attr "mode" "DI")])
4950
 
4951
;; The lea patterns for non-Pmodes needs to be matched by several
4952
;; insns converted to real lea by splitters.
4953
 
4954
(define_insn_and_split "*lea_general_1"
4955
  [(set (match_operand 0 "register_operand" "=r")
4956
        (plus (plus (match_operand 1 "index_register_operand" "l")
4957
                    (match_operand 2 "register_operand" "r"))
4958
              (match_operand 3 "immediate_operand" "i")))]
4959
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4960
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4961
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4962
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4963
   && GET_MODE (operands[0]) == GET_MODE (operands[2])
4964
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4965
       || GET_MODE (operands[3]) == VOIDmode)"
4966
  "#"
4967
  "&& reload_completed"
4968
  [(const_int 0)]
4969
{
4970
  rtx pat;
4971
  operands[0] = gen_lowpart (SImode, operands[0]);
4972
  operands[1] = gen_lowpart (Pmode, operands[1]);
4973
  operands[2] = gen_lowpart (Pmode, operands[2]);
4974
  operands[3] = gen_lowpart (Pmode, operands[3]);
4975
  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4976
                      operands[3]);
4977
  if (Pmode != SImode)
4978
    pat = gen_rtx_SUBREG (SImode, pat, 0);
4979
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4980
  DONE;
4981
}
4982
  [(set_attr "type" "lea")
4983
   (set_attr "mode" "SI")])
4984
 
4985
(define_insn_and_split "*lea_general_1_zext"
4986
  [(set (match_operand:DI 0 "register_operand" "=r")
4987
        (zero_extend:DI
4988
          (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4989
                            (match_operand:SI 2 "register_operand" "r"))
4990
                   (match_operand:SI 3 "immediate_operand" "i"))))]
4991
  "TARGET_64BIT"
4992
  "#"
4993
  "&& reload_completed"
4994
  [(set (match_dup 0)
4995
        (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4996
                                                     (match_dup 2))
4997
                                            (match_dup 3)) 0)))]
4998
{
4999
  operands[1] = gen_lowpart (Pmode, operands[1]);
5000
  operands[2] = gen_lowpart (Pmode, operands[2]);
5001
  operands[3] = gen_lowpart (Pmode, operands[3]);
5002
}
5003
  [(set_attr "type" "lea")
5004
   (set_attr "mode" "SI")])
5005
 
5006
(define_insn_and_split "*lea_general_2"
5007
  [(set (match_operand 0 "register_operand" "=r")
5008
        (plus (mult (match_operand 1 "index_register_operand" "l")
5009
                    (match_operand 2 "const248_operand" "i"))
5010
              (match_operand 3 "nonmemory_operand" "ri")))]
5011
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5012
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5013
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5014
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5015
   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5016
       || GET_MODE (operands[3]) == VOIDmode)"
5017
  "#"
5018
  "&& reload_completed"
5019
  [(const_int 0)]
5020
{
5021
  rtx pat;
5022
  operands[0] = gen_lowpart (SImode, operands[0]);
5023
  operands[1] = gen_lowpart (Pmode, operands[1]);
5024
  operands[3] = gen_lowpart (Pmode, operands[3]);
5025
  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5026
                      operands[3]);
5027
  if (Pmode != SImode)
5028
    pat = gen_rtx_SUBREG (SImode, pat, 0);
5029
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5030
  DONE;
5031
}
5032
  [(set_attr "type" "lea")
5033
   (set_attr "mode" "SI")])
5034
 
5035
(define_insn_and_split "*lea_general_2_zext"
5036
  [(set (match_operand:DI 0 "register_operand" "=r")
5037
        (zero_extend:DI
5038
          (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5039
                            (match_operand:SI 2 "const248_operand" "n"))
5040
                   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5041
  "TARGET_64BIT"
5042
  "#"
5043
  "&& reload_completed"
5044
  [(set (match_dup 0)
5045
        (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5046
                                                     (match_dup 2))
5047
                                            (match_dup 3)) 0)))]
5048
{
5049
  operands[1] = gen_lowpart (Pmode, operands[1]);
5050
  operands[3] = gen_lowpart (Pmode, operands[3]);
5051
}
5052
  [(set_attr "type" "lea")
5053
   (set_attr "mode" "SI")])
5054
 
5055
(define_insn_and_split "*lea_general_3"
5056
  [(set (match_operand 0 "register_operand" "=r")
5057
        (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5058
                          (match_operand 2 "const248_operand" "i"))
5059
                    (match_operand 3 "register_operand" "r"))
5060
              (match_operand 4 "immediate_operand" "i")))]
5061
  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5062
    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5063
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5064
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5065
   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5066
  "#"
5067
  "&& reload_completed"
5068
  [(const_int 0)]
5069
{
5070
  rtx pat;
5071
  operands[0] = gen_lowpart (SImode, operands[0]);
5072
  operands[1] = gen_lowpart (Pmode, operands[1]);
5073
  operands[3] = gen_lowpart (Pmode, operands[3]);
5074
  operands[4] = gen_lowpart (Pmode, operands[4]);
5075
  pat = gen_rtx_PLUS (Pmode,
5076
                      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5077
                                                         operands[2]),
5078
                                    operands[3]),
5079
                      operands[4]);
5080
  if (Pmode != SImode)
5081
    pat = gen_rtx_SUBREG (SImode, pat, 0);
5082
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5083
  DONE;
5084
}
5085
  [(set_attr "type" "lea")
5086
   (set_attr "mode" "SI")])
5087
 
5088
(define_insn_and_split "*lea_general_3_zext"
5089
  [(set (match_operand:DI 0 "register_operand" "=r")
5090
        (zero_extend:DI
5091
          (plus:SI (plus:SI (mult:SI
5092
                              (match_operand:SI 1 "index_register_operand" "l")
5093
                              (match_operand:SI 2 "const248_operand" "n"))
5094
                            (match_operand:SI 3 "register_operand" "r"))
5095
                   (match_operand:SI 4 "immediate_operand" "i"))))]
5096
  "TARGET_64BIT"
5097
  "#"
5098
  "&& reload_completed"
5099
  [(set (match_dup 0)
5100
        (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5101
                                                              (match_dup 2))
5102
                                                     (match_dup 3))
5103
                                            (match_dup 4)) 0)))]
5104
{
5105
  operands[1] = gen_lowpart (Pmode, operands[1]);
5106
  operands[3] = gen_lowpart (Pmode, operands[3]);
5107
  operands[4] = gen_lowpart (Pmode, operands[4]);
5108
}
5109
  [(set_attr "type" "lea")
5110
   (set_attr "mode" "SI")])
5111
 
5112
(define_insn "*adddi_1_rex64"
5113
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5114
        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5115
                 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5116
   (clobber (reg:CC FLAGS_REG))]
5117
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5118
{
5119
  switch (get_attr_type (insn))
5120
    {
5121
    case TYPE_LEA:
5122
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5123
      return "lea{q}\t{%a2, %0|%0, %a2}";
5124
 
5125
    case TYPE_INCDEC:
5126
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5127
      if (operands[2] == const1_rtx)
5128
        return "inc{q}\t%0";
5129
      else
5130
        {
5131
          gcc_assert (operands[2] == constm1_rtx);
5132
          return "dec{q}\t%0";
5133
        }
5134
 
5135
    default:
5136
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5137
 
5138
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5139
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5140
      if (GET_CODE (operands[2]) == CONST_INT
5141
          /* Avoid overflows.  */
5142
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5143
          && (INTVAL (operands[2]) == 128
5144
              || (INTVAL (operands[2]) < 0
5145
                  && INTVAL (operands[2]) != -128)))
5146
        {
5147
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5148
          return "sub{q}\t{%2, %0|%0, %2}";
5149
        }
5150
      return "add{q}\t{%2, %0|%0, %2}";
5151
    }
5152
}
5153
  [(set (attr "type")
5154
     (cond [(eq_attr "alternative" "2")
5155
              (const_string "lea")
5156
            ; Current assemblers are broken and do not allow @GOTOFF in
5157
            ; ought but a memory context.
5158
            (match_operand:DI 2 "pic_symbolic_operand" "")
5159
              (const_string "lea")
5160
            (match_operand:DI 2 "incdec_operand" "")
5161
              (const_string "incdec")
5162
           ]
5163
           (const_string "alu")))
5164
   (set_attr "mode" "DI")])
5165
 
5166
;; Convert lea to the lea pattern to avoid flags dependency.
5167
(define_split
5168
  [(set (match_operand:DI 0 "register_operand" "")
5169
        (plus:DI (match_operand:DI 1 "register_operand" "")
5170
                 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5171
   (clobber (reg:CC FLAGS_REG))]
5172
  "TARGET_64BIT && reload_completed
5173
   && true_regnum (operands[0]) != true_regnum (operands[1])"
5174
  [(set (match_dup 0)
5175
        (plus:DI (match_dup 1)
5176
                 (match_dup 2)))]
5177
  "")
5178
 
5179
(define_insn "*adddi_2_rex64"
5180
  [(set (reg FLAGS_REG)
5181
        (compare
5182
          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5183
                   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5184
          (const_int 0)))
5185
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5186
        (plus:DI (match_dup 1) (match_dup 2)))]
5187
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5188
   && ix86_binary_operator_ok (PLUS, DImode, operands)
5189
   /* Current assemblers are broken and do not allow @GOTOFF in
5190
      ought but a memory context.  */
5191
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5192
{
5193
  switch (get_attr_type (insn))
5194
    {
5195
    case TYPE_INCDEC:
5196
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5197
      if (operands[2] == const1_rtx)
5198
        return "inc{q}\t%0";
5199
      else
5200
        {
5201
          gcc_assert (operands[2] == constm1_rtx);
5202
          return "dec{q}\t%0";
5203
        }
5204
 
5205
    default:
5206
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5207
      /* ???? We ought to handle there the 32bit case too
5208
         - do we need new constraint?  */
5209
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5210
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5211
      if (GET_CODE (operands[2]) == CONST_INT
5212
          /* Avoid overflows.  */
5213
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5214
          && (INTVAL (operands[2]) == 128
5215
              || (INTVAL (operands[2]) < 0
5216
                  && INTVAL (operands[2]) != -128)))
5217
        {
5218
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5219
          return "sub{q}\t{%2, %0|%0, %2}";
5220
        }
5221
      return "add{q}\t{%2, %0|%0, %2}";
5222
    }
5223
}
5224
  [(set (attr "type")
5225
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5226
        (const_string "incdec")
5227
        (const_string "alu")))
5228
   (set_attr "mode" "DI")])
5229
 
5230
(define_insn "*adddi_3_rex64"
5231
  [(set (reg FLAGS_REG)
5232
        (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5233
                 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5234
   (clobber (match_scratch:DI 0 "=r"))]
5235
  "TARGET_64BIT
5236
   && ix86_match_ccmode (insn, CCZmode)
5237
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5238
   /* Current assemblers are broken and do not allow @GOTOFF in
5239
      ought but a memory context.  */
5240
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5241
{
5242
  switch (get_attr_type (insn))
5243
    {
5244
    case TYPE_INCDEC:
5245
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5246
      if (operands[2] == const1_rtx)
5247
        return "inc{q}\t%0";
5248
      else
5249
        {
5250
          gcc_assert (operands[2] == constm1_rtx);
5251
          return "dec{q}\t%0";
5252
        }
5253
 
5254
    default:
5255
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5256
      /* ???? We ought to handle there the 32bit case too
5257
         - do we need new constraint?  */
5258
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5259
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5260
      if (GET_CODE (operands[2]) == CONST_INT
5261
          /* Avoid overflows.  */
5262
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5263
          && (INTVAL (operands[2]) == 128
5264
              || (INTVAL (operands[2]) < 0
5265
                  && INTVAL (operands[2]) != -128)))
5266
        {
5267
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5268
          return "sub{q}\t{%2, %0|%0, %2}";
5269
        }
5270
      return "add{q}\t{%2, %0|%0, %2}";
5271
    }
5272
}
5273
  [(set (attr "type")
5274
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5275
        (const_string "incdec")
5276
        (const_string "alu")))
5277
   (set_attr "mode" "DI")])
5278
 
5279
; For comparisons against 1, -1 and 128, we may generate better code
5280
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5281
; is matched then.  We can't accept general immediate, because for
5282
; case of overflows,  the result is messed up.
5283
; This pattern also don't hold of 0x8000000000000000, since the value overflows
5284
; when negated.
5285
; Also carry flag is reversed compared to cmp, so this conversion is valid
5286
; only for comparisons not depending on it.
5287
(define_insn "*adddi_4_rex64"
5288
  [(set (reg FLAGS_REG)
5289
        (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5290
                 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5291
   (clobber (match_scratch:DI 0 "=rm"))]
5292
  "TARGET_64BIT
5293
   &&  ix86_match_ccmode (insn, CCGCmode)"
5294
{
5295
  switch (get_attr_type (insn))
5296
    {
5297
    case TYPE_INCDEC:
5298
      if (operands[2] == constm1_rtx)
5299
        return "inc{q}\t%0";
5300
      else
5301
        {
5302
          gcc_assert (operands[2] == const1_rtx);
5303
          return "dec{q}\t%0";
5304
        }
5305
 
5306
    default:
5307
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5308
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5309
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5310
      if ((INTVAL (operands[2]) == -128
5311
           || (INTVAL (operands[2]) > 0
5312
               && INTVAL (operands[2]) != 128))
5313
          /* Avoid overflows.  */
5314
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5315
        return "sub{q}\t{%2, %0|%0, %2}";
5316
      operands[2] = GEN_INT (-INTVAL (operands[2]));
5317
      return "add{q}\t{%2, %0|%0, %2}";
5318
    }
5319
}
5320
  [(set (attr "type")
5321
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5322
        (const_string "incdec")
5323
        (const_string "alu")))
5324
   (set_attr "mode" "DI")])
5325
 
5326
(define_insn "*adddi_5_rex64"
5327
  [(set (reg FLAGS_REG)
5328
        (compare
5329
          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5330
                   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5331
          (const_int 0)))
5332
   (clobber (match_scratch:DI 0 "=r"))]
5333
  "TARGET_64BIT
5334
   && ix86_match_ccmode (insn, CCGOCmode)
5335
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5336
   /* Current assemblers are broken and do not allow @GOTOFF in
5337
      ought but a memory context.  */
5338
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5339
{
5340
  switch (get_attr_type (insn))
5341
    {
5342
    case TYPE_INCDEC:
5343
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5344
      if (operands[2] == const1_rtx)
5345
        return "inc{q}\t%0";
5346
      else
5347
        {
5348
          gcc_assert (operands[2] == constm1_rtx);
5349
          return "dec{q}\t%0";
5350
        }
5351
 
5352
    default:
5353
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5355
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5356
      if (GET_CODE (operands[2]) == CONST_INT
5357
          /* Avoid overflows.  */
5358
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5359
          && (INTVAL (operands[2]) == 128
5360
              || (INTVAL (operands[2]) < 0
5361
                  && INTVAL (operands[2]) != -128)))
5362
        {
5363
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5364
          return "sub{q}\t{%2, %0|%0, %2}";
5365
        }
5366
      return "add{q}\t{%2, %0|%0, %2}";
5367
    }
5368
}
5369
  [(set (attr "type")
5370
     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5371
        (const_string "incdec")
5372
        (const_string "alu")))
5373
   (set_attr "mode" "DI")])
5374
 
5375
 
5376
(define_insn "*addsi_1"
5377
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5378
        (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5379
                 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5380
   (clobber (reg:CC FLAGS_REG))]
5381
  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5382
{
5383
  switch (get_attr_type (insn))
5384
    {
5385
    case TYPE_LEA:
5386
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5387
      return "lea{l}\t{%a2, %0|%0, %a2}";
5388
 
5389
    case TYPE_INCDEC:
5390
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5391
      if (operands[2] == const1_rtx)
5392
        return "inc{l}\t%0";
5393
      else
5394
        {
5395
          gcc_assert (operands[2] == constm1_rtx);
5396
          return "dec{l}\t%0";
5397
        }
5398
 
5399
    default:
5400
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401
 
5402
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5403
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5404
      if (GET_CODE (operands[2]) == CONST_INT
5405
          && (INTVAL (operands[2]) == 128
5406
              || (INTVAL (operands[2]) < 0
5407
                  && INTVAL (operands[2]) != -128)))
5408
        {
5409
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5410
          return "sub{l}\t{%2, %0|%0, %2}";
5411
        }
5412
      return "add{l}\t{%2, %0|%0, %2}";
5413
    }
5414
}
5415
  [(set (attr "type")
5416
     (cond [(eq_attr "alternative" "2")
5417
              (const_string "lea")
5418
            ; Current assemblers are broken and do not allow @GOTOFF in
5419
            ; ought but a memory context.
5420
            (match_operand:SI 2 "pic_symbolic_operand" "")
5421
              (const_string "lea")
5422
            (match_operand:SI 2 "incdec_operand" "")
5423
              (const_string "incdec")
5424
           ]
5425
           (const_string "alu")))
5426
   (set_attr "mode" "SI")])
5427
 
5428
;; Convert lea to the lea pattern to avoid flags dependency.
5429
(define_split
5430
  [(set (match_operand 0 "register_operand" "")
5431
        (plus (match_operand 1 "register_operand" "")
5432
              (match_operand 2 "nonmemory_operand" "")))
5433
   (clobber (reg:CC FLAGS_REG))]
5434
  "reload_completed
5435
   && true_regnum (operands[0]) != true_regnum (operands[1])"
5436
  [(const_int 0)]
5437
{
5438
  rtx pat;
5439
  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5440
     may confuse gen_lowpart.  */
5441
  if (GET_MODE (operands[0]) != Pmode)
5442
    {
5443
      operands[1] = gen_lowpart (Pmode, operands[1]);
5444
      operands[2] = gen_lowpart (Pmode, operands[2]);
5445
    }
5446
  operands[0] = gen_lowpart (SImode, operands[0]);
5447
  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5448
  if (Pmode != SImode)
5449
    pat = gen_rtx_SUBREG (SImode, pat, 0);
5450
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5451
  DONE;
5452
})
5453
 
5454
;; It may seem that nonimmediate operand is proper one for operand 1.
5455
;; The addsi_1 pattern allows nonimmediate operand at that place and
5456
;; we take care in ix86_binary_operator_ok to not allow two memory
5457
;; operands so proper swapping will be done in reload.  This allow
5458
;; patterns constructed from addsi_1 to match.
5459
(define_insn "addsi_1_zext"
5460
  [(set (match_operand:DI 0 "register_operand" "=r,r")
5461
        (zero_extend:DI
5462
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5463
                   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5464
   (clobber (reg:CC FLAGS_REG))]
5465
  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5466
{
5467
  switch (get_attr_type (insn))
5468
    {
5469
    case TYPE_LEA:
5470
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5471
      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5472
 
5473
    case TYPE_INCDEC:
5474
      if (operands[2] == const1_rtx)
5475
        return "inc{l}\t%k0";
5476
      else
5477
        {
5478
          gcc_assert (operands[2] == constm1_rtx);
5479
          return "dec{l}\t%k0";
5480
        }
5481
 
5482
    default:
5483
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5484
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5485
      if (GET_CODE (operands[2]) == CONST_INT
5486
          && (INTVAL (operands[2]) == 128
5487
              || (INTVAL (operands[2]) < 0
5488
                  && INTVAL (operands[2]) != -128)))
5489
        {
5490
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5491
          return "sub{l}\t{%2, %k0|%k0, %2}";
5492
        }
5493
      return "add{l}\t{%2, %k0|%k0, %2}";
5494
    }
5495
}
5496
  [(set (attr "type")
5497
     (cond [(eq_attr "alternative" "1")
5498
              (const_string "lea")
5499
            ; Current assemblers are broken and do not allow @GOTOFF in
5500
            ; ought but a memory context.
5501
            (match_operand:SI 2 "pic_symbolic_operand" "")
5502
              (const_string "lea")
5503
            (match_operand:SI 2 "incdec_operand" "")
5504
              (const_string "incdec")
5505
           ]
5506
           (const_string "alu")))
5507
   (set_attr "mode" "SI")])
5508
 
5509
;; Convert lea to the lea pattern to avoid flags dependency.
5510
(define_split
5511
  [(set (match_operand:DI 0 "register_operand" "")
5512
        (zero_extend:DI
5513
          (plus:SI (match_operand:SI 1 "register_operand" "")
5514
                   (match_operand:SI 2 "nonmemory_operand" ""))))
5515
   (clobber (reg:CC FLAGS_REG))]
5516
  "TARGET_64BIT && reload_completed
5517
   && true_regnum (operands[0]) != true_regnum (operands[1])"
5518
  [(set (match_dup 0)
5519
        (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5520
{
5521
  operands[1] = gen_lowpart (Pmode, operands[1]);
5522
  operands[2] = gen_lowpart (Pmode, operands[2]);
5523
})
5524
 
5525
(define_insn "*addsi_2"
5526
  [(set (reg FLAGS_REG)
5527
        (compare
5528
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5529
                   (match_operand:SI 2 "general_operand" "rmni,rni"))
5530
          (const_int 0)))
5531
   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5532
        (plus:SI (match_dup 1) (match_dup 2)))]
5533
  "ix86_match_ccmode (insn, CCGOCmode)
5534
   && ix86_binary_operator_ok (PLUS, SImode, operands)
5535
   /* Current assemblers are broken and do not allow @GOTOFF in
5536
      ought but a memory context.  */
5537
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5538
{
5539
  switch (get_attr_type (insn))
5540
    {
5541
    case TYPE_INCDEC:
5542
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543
      if (operands[2] == const1_rtx)
5544
        return "inc{l}\t%0";
5545
      else
5546
        {
5547
          gcc_assert (operands[2] == constm1_rtx);
5548
          return "dec{l}\t%0";
5549
        }
5550
 
5551
    default:
5552
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5553
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5554
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5555
      if (GET_CODE (operands[2]) == CONST_INT
5556
          && (INTVAL (operands[2]) == 128
5557
              || (INTVAL (operands[2]) < 0
5558
                  && INTVAL (operands[2]) != -128)))
5559
        {
5560
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5561
          return "sub{l}\t{%2, %0|%0, %2}";
5562
        }
5563
      return "add{l}\t{%2, %0|%0, %2}";
5564
    }
5565
}
5566
  [(set (attr "type")
5567
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5568
        (const_string "incdec")
5569
        (const_string "alu")))
5570
   (set_attr "mode" "SI")])
5571
 
5572
;; See comment for addsi_1_zext why we do use nonimmediate_operand
5573
(define_insn "*addsi_2_zext"
5574
  [(set (reg FLAGS_REG)
5575
        (compare
5576
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5577
                   (match_operand:SI 2 "general_operand" "rmni"))
5578
          (const_int 0)))
5579
   (set (match_operand:DI 0 "register_operand" "=r")
5580
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5581
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5582
   && ix86_binary_operator_ok (PLUS, SImode, operands)
5583
   /* Current assemblers are broken and do not allow @GOTOFF in
5584
      ought but a memory context.  */
5585
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586
{
5587
  switch (get_attr_type (insn))
5588
    {
5589
    case TYPE_INCDEC:
5590
      if (operands[2] == const1_rtx)
5591
        return "inc{l}\t%k0";
5592
      else
5593
        {
5594
          gcc_assert (operands[2] == constm1_rtx);
5595
          return "dec{l}\t%k0";
5596
        }
5597
 
5598
    default:
5599
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5600
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5601
      if (GET_CODE (operands[2]) == CONST_INT
5602
          && (INTVAL (operands[2]) == 128
5603
              || (INTVAL (operands[2]) < 0
5604
                  && INTVAL (operands[2]) != -128)))
5605
        {
5606
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5607
          return "sub{l}\t{%2, %k0|%k0, %2}";
5608
        }
5609
      return "add{l}\t{%2, %k0|%k0, %2}";
5610
    }
5611
}
5612
  [(set (attr "type")
5613
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5614
        (const_string "incdec")
5615
        (const_string "alu")))
5616
   (set_attr "mode" "SI")])
5617
 
5618
(define_insn "*addsi_3"
5619
  [(set (reg FLAGS_REG)
5620
        (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5621
                 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5622
   (clobber (match_scratch:SI 0 "=r"))]
5623
  "ix86_match_ccmode (insn, CCZmode)
5624
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5625
   /* Current assemblers are broken and do not allow @GOTOFF in
5626
      ought but a memory context.  */
5627
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5628
{
5629
  switch (get_attr_type (insn))
5630
    {
5631
    case TYPE_INCDEC:
5632
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633
      if (operands[2] == const1_rtx)
5634
        return "inc{l}\t%0";
5635
      else
5636
        {
5637
          gcc_assert (operands[2] == constm1_rtx);
5638
          return "dec{l}\t%0";
5639
        }
5640
 
5641
    default:
5642
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5644
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5645
      if (GET_CODE (operands[2]) == CONST_INT
5646
          && (INTVAL (operands[2]) == 128
5647
              || (INTVAL (operands[2]) < 0
5648
                  && INTVAL (operands[2]) != -128)))
5649
        {
5650
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5651
          return "sub{l}\t{%2, %0|%0, %2}";
5652
        }
5653
      return "add{l}\t{%2, %0|%0, %2}";
5654
    }
5655
}
5656
  [(set (attr "type")
5657
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5658
        (const_string "incdec")
5659
        (const_string "alu")))
5660
   (set_attr "mode" "SI")])
5661
 
5662
;; See comment for addsi_1_zext why we do use nonimmediate_operand
5663
(define_insn "*addsi_3_zext"
5664
  [(set (reg FLAGS_REG)
5665
        (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5666
                 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5667
   (set (match_operand:DI 0 "register_operand" "=r")
5668
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5669
  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5670
   && ix86_binary_operator_ok (PLUS, SImode, operands)
5671
   /* Current assemblers are broken and do not allow @GOTOFF in
5672
      ought but a memory context.  */
5673
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674
{
5675
  switch (get_attr_type (insn))
5676
    {
5677
    case TYPE_INCDEC:
5678
      if (operands[2] == const1_rtx)
5679
        return "inc{l}\t%k0";
5680
      else
5681
        {
5682
          gcc_assert (operands[2] == constm1_rtx);
5683
          return "dec{l}\t%k0";
5684
        }
5685
 
5686
    default:
5687
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5688
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5689
      if (GET_CODE (operands[2]) == CONST_INT
5690
          && (INTVAL (operands[2]) == 128
5691
              || (INTVAL (operands[2]) < 0
5692
                  && INTVAL (operands[2]) != -128)))
5693
        {
5694
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5695
          return "sub{l}\t{%2, %k0|%k0, %2}";
5696
        }
5697
      return "add{l}\t{%2, %k0|%k0, %2}";
5698
    }
5699
}
5700
  [(set (attr "type")
5701
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5702
        (const_string "incdec")
5703
        (const_string "alu")))
5704
   (set_attr "mode" "SI")])
5705
 
5706
; For comparisons against 1, -1 and 128, we may generate better code
5707
; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5708
; is matched then.  We can't accept general immediate, because for
5709
; case of overflows,  the result is messed up.
5710
; This pattern also don't hold of 0x80000000, since the value overflows
5711
; when negated.
5712
; Also carry flag is reversed compared to cmp, so this conversion is valid
5713
; only for comparisons not depending on it.
5714
(define_insn "*addsi_4"
5715
  [(set (reg FLAGS_REG)
5716
        (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5717
                 (match_operand:SI 2 "const_int_operand" "n")))
5718
   (clobber (match_scratch:SI 0 "=rm"))]
5719
  "ix86_match_ccmode (insn, CCGCmode)
5720
   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5721
{
5722
  switch (get_attr_type (insn))
5723
    {
5724
    case TYPE_INCDEC:
5725
      if (operands[2] == constm1_rtx)
5726
        return "inc{l}\t%0";
5727
      else
5728
        {
5729
          gcc_assert (operands[2] == const1_rtx);
5730
          return "dec{l}\t%0";
5731
        }
5732
 
5733
    default:
5734
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5735
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5737
      if ((INTVAL (operands[2]) == -128
5738
           || (INTVAL (operands[2]) > 0
5739
               && INTVAL (operands[2]) != 128)))
5740
        return "sub{l}\t{%2, %0|%0, %2}";
5741
      operands[2] = GEN_INT (-INTVAL (operands[2]));
5742
      return "add{l}\t{%2, %0|%0, %2}";
5743
    }
5744
}
5745
  [(set (attr "type")
5746
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5747
        (const_string "incdec")
5748
        (const_string "alu")))
5749
   (set_attr "mode" "SI")])
5750
 
5751
(define_insn "*addsi_5"
5752
  [(set (reg FLAGS_REG)
5753
        (compare
5754
          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5755
                   (match_operand:SI 2 "general_operand" "rmni"))
5756
          (const_int 0)))
5757
   (clobber (match_scratch:SI 0 "=r"))]
5758
  "ix86_match_ccmode (insn, CCGOCmode)
5759
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5760
   /* Current assemblers are broken and do not allow @GOTOFF in
5761
      ought but a memory context.  */
5762
   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5763
{
5764
  switch (get_attr_type (insn))
5765
    {
5766
    case TYPE_INCDEC:
5767
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5768
      if (operands[2] == const1_rtx)
5769
        return "inc{l}\t%0";
5770
      else
5771
        {
5772
          gcc_assert (operands[2] == constm1_rtx);
5773
          return "dec{l}\t%0";
5774
        }
5775
 
5776
    default:
5777
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5780
      if (GET_CODE (operands[2]) == CONST_INT
5781
          && (INTVAL (operands[2]) == 128
5782
              || (INTVAL (operands[2]) < 0
5783
                  && INTVAL (operands[2]) != -128)))
5784
        {
5785
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5786
          return "sub{l}\t{%2, %0|%0, %2}";
5787
        }
5788
      return "add{l}\t{%2, %0|%0, %2}";
5789
    }
5790
}
5791
  [(set (attr "type")
5792
     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5793
        (const_string "incdec")
5794
        (const_string "alu")))
5795
   (set_attr "mode" "SI")])
5796
 
5797
(define_expand "addhi3"
5798
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5799
                   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5800
                            (match_operand:HI 2 "general_operand" "")))
5801
              (clobber (reg:CC FLAGS_REG))])]
5802
  "TARGET_HIMODE_MATH"
5803
  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5804
 
5805
;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5806
;; type optimizations enabled by define-splits.  This is not important
5807
;; for PII, and in fact harmful because of partial register stalls.
5808
 
5809
(define_insn "*addhi_1_lea"
5810
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5811
        (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5812
                 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5813
   (clobber (reg:CC FLAGS_REG))]
5814
  "!TARGET_PARTIAL_REG_STALL
5815
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5816
{
5817
  switch (get_attr_type (insn))
5818
    {
5819
    case TYPE_LEA:
5820
      return "#";
5821
    case TYPE_INCDEC:
5822
      if (operands[2] == const1_rtx)
5823
        return "inc{w}\t%0";
5824
      else
5825
        {
5826
          gcc_assert (operands[2] == constm1_rtx);
5827
          return "dec{w}\t%0";
5828
        }
5829
 
5830
    default:
5831
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833
      if (GET_CODE (operands[2]) == CONST_INT
5834
          && (INTVAL (operands[2]) == 128
5835
              || (INTVAL (operands[2]) < 0
5836
                  && INTVAL (operands[2]) != -128)))
5837
        {
5838
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5839
          return "sub{w}\t{%2, %0|%0, %2}";
5840
        }
5841
      return "add{w}\t{%2, %0|%0, %2}";
5842
    }
5843
}
5844
  [(set (attr "type")
5845
     (if_then_else (eq_attr "alternative" "2")
5846
        (const_string "lea")
5847
        (if_then_else (match_operand:HI 2 "incdec_operand" "")
5848
           (const_string "incdec")
5849
           (const_string "alu"))))
5850
   (set_attr "mode" "HI,HI,SI")])
5851
 
5852
(define_insn "*addhi_1"
5853
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5854
        (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5855
                 (match_operand:HI 2 "general_operand" "ri,rm")))
5856
   (clobber (reg:CC FLAGS_REG))]
5857
  "TARGET_PARTIAL_REG_STALL
5858
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5859
{
5860
  switch (get_attr_type (insn))
5861
    {
5862
    case TYPE_INCDEC:
5863
      if (operands[2] == const1_rtx)
5864
        return "inc{w}\t%0";
5865
      else
5866
        {
5867
          gcc_assert (operands[2] == constm1_rtx);
5868
          return "dec{w}\t%0";
5869
        }
5870
 
5871
    default:
5872
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874
      if (GET_CODE (operands[2]) == CONST_INT
5875
          && (INTVAL (operands[2]) == 128
5876
              || (INTVAL (operands[2]) < 0
5877
                  && INTVAL (operands[2]) != -128)))
5878
        {
5879
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5880
          return "sub{w}\t{%2, %0|%0, %2}";
5881
        }
5882
      return "add{w}\t{%2, %0|%0, %2}";
5883
    }
5884
}
5885
  [(set (attr "type")
5886
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5887
        (const_string "incdec")
5888
        (const_string "alu")))
5889
   (set_attr "mode" "HI")])
5890
 
5891
(define_insn "*addhi_2"
5892
  [(set (reg FLAGS_REG)
5893
        (compare
5894
          (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5895
                   (match_operand:HI 2 "general_operand" "rmni,rni"))
5896
          (const_int 0)))
5897
   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5898
        (plus:HI (match_dup 1) (match_dup 2)))]
5899
  "ix86_match_ccmode (insn, CCGOCmode)
5900
   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5901
{
5902
  switch (get_attr_type (insn))
5903
    {
5904
    case TYPE_INCDEC:
5905
      if (operands[2] == const1_rtx)
5906
        return "inc{w}\t%0";
5907
      else
5908
        {
5909
          gcc_assert (operands[2] == constm1_rtx);
5910
          return "dec{w}\t%0";
5911
        }
5912
 
5913
    default:
5914
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916
      if (GET_CODE (operands[2]) == CONST_INT
5917
          && (INTVAL (operands[2]) == 128
5918
              || (INTVAL (operands[2]) < 0
5919
                  && INTVAL (operands[2]) != -128)))
5920
        {
5921
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5922
          return "sub{w}\t{%2, %0|%0, %2}";
5923
        }
5924
      return "add{w}\t{%2, %0|%0, %2}";
5925
    }
5926
}
5927
  [(set (attr "type")
5928
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929
        (const_string "incdec")
5930
        (const_string "alu")))
5931
   (set_attr "mode" "HI")])
5932
 
5933
(define_insn "*addhi_3"
5934
  [(set (reg FLAGS_REG)
5935
        (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5936
                 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5937
   (clobber (match_scratch:HI 0 "=r"))]
5938
  "ix86_match_ccmode (insn, CCZmode)
5939
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5940
{
5941
  switch (get_attr_type (insn))
5942
    {
5943
    case TYPE_INCDEC:
5944
      if (operands[2] == const1_rtx)
5945
        return "inc{w}\t%0";
5946
      else
5947
        {
5948
          gcc_assert (operands[2] == constm1_rtx);
5949
          return "dec{w}\t%0";
5950
        }
5951
 
5952
    default:
5953
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5954
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5955
      if (GET_CODE (operands[2]) == CONST_INT
5956
          && (INTVAL (operands[2]) == 128
5957
              || (INTVAL (operands[2]) < 0
5958
                  && INTVAL (operands[2]) != -128)))
5959
        {
5960
          operands[2] = GEN_INT (-INTVAL (operands[2]));
5961
          return "sub{w}\t{%2, %0|%0, %2}";
5962
        }
5963
      return "add{w}\t{%2, %0|%0, %2}";
5964
    }
5965
}
5966
  [(set (attr "type")
5967
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5968
        (const_string "incdec")
5969
        (const_string "alu")))
5970
   (set_attr "mode" "HI")])
5971
 
5972
; See comments above addsi_4 for details.
5973
(define_insn "*addhi_4"
5974
  [(set (reg FLAGS_REG)
5975
        (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5976
                 (match_operand:HI 2 "const_int_operand" "n")))
5977
   (clobber (match_scratch:HI 0 "=rm"))]
5978
  "ix86_match_ccmode (insn, CCGCmode)
5979
   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5980
{
5981
  switch (get_attr_type (insn))
5982
    {
5983
    case TYPE_INCDEC:
5984
      if (operands[2] == constm1_rtx)
5985
        return "inc{w}\t%0";
5986
      else
5987
        {
5988
          gcc_assert (operands[2] == const1_rtx);
5989
          return "dec{w}\t%0";
5990
        }
5991
 
5992
    default:
5993
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5996
      if ((INTVAL (operands[2]) == -128
5997
           || (INTVAL (operands[2]) > 0
5998
               && INTVAL (operands[2]) != 128)))
5999
        return "sub{w}\t{%2, %0|%0, %2}";
6000
      operands[2] = GEN_INT (-INTVAL (operands[2]));
6001
      return "add{w}\t{%2, %0|%0, %2}";
6002
    }
6003
}
6004
  [(set (attr "type")
6005
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006
        (const_string "incdec")
6007
        (const_string "alu")))
6008
   (set_attr "mode" "SI")])
6009
 
6010
 
6011
(define_insn "*addhi_5"
6012
  [(set (reg FLAGS_REG)
6013
        (compare
6014
          (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6015
                   (match_operand:HI 2 "general_operand" "rmni"))
6016
          (const_int 0)))
6017
   (clobber (match_scratch:HI 0 "=r"))]
6018
  "ix86_match_ccmode (insn, CCGOCmode)
6019
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6020
{
6021
  switch (get_attr_type (insn))
6022
    {
6023
    case TYPE_INCDEC:
6024
      if (operands[2] == const1_rtx)
6025
        return "inc{w}\t%0";
6026
      else
6027
        {
6028
          gcc_assert (operands[2] == constm1_rtx);
6029
          return "dec{w}\t%0";
6030
        }
6031
 
6032
    default:
6033
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6034
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6035
      if (GET_CODE (operands[2]) == CONST_INT
6036
          && (INTVAL (operands[2]) == 128
6037
              || (INTVAL (operands[2]) < 0
6038
                  && INTVAL (operands[2]) != -128)))
6039
        {
6040
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6041
          return "sub{w}\t{%2, %0|%0, %2}";
6042
        }
6043
      return "add{w}\t{%2, %0|%0, %2}";
6044
    }
6045
}
6046
  [(set (attr "type")
6047
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6048
        (const_string "incdec")
6049
        (const_string "alu")))
6050
   (set_attr "mode" "HI")])
6051
 
6052
(define_expand "addqi3"
6053
  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6054
                   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6055
                            (match_operand:QI 2 "general_operand" "")))
6056
              (clobber (reg:CC FLAGS_REG))])]
6057
  "TARGET_QIMODE_MATH"
6058
  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6059
 
6060
;; %%% Potential partial reg stall on alternative 2.  What to do?
6061
(define_insn "*addqi_1_lea"
6062
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6063
        (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6064
                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6065
   (clobber (reg:CC FLAGS_REG))]
6066
  "!TARGET_PARTIAL_REG_STALL
6067
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6068
{
6069
  int widen = (which_alternative == 2);
6070
  switch (get_attr_type (insn))
6071
    {
6072
    case TYPE_LEA:
6073
      return "#";
6074
    case TYPE_INCDEC:
6075
      if (operands[2] == const1_rtx)
6076
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6077
      else
6078
        {
6079
          gcc_assert (operands[2] == constm1_rtx);
6080
          return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6081
        }
6082
 
6083
    default:
6084
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6086
      if (GET_CODE (operands[2]) == CONST_INT
6087
          && (INTVAL (operands[2]) == 128
6088
              || (INTVAL (operands[2]) < 0
6089
                  && INTVAL (operands[2]) != -128)))
6090
        {
6091
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6092
          if (widen)
6093
            return "sub{l}\t{%2, %k0|%k0, %2}";
6094
          else
6095
            return "sub{b}\t{%2, %0|%0, %2}";
6096
        }
6097
      if (widen)
6098
        return "add{l}\t{%k2, %k0|%k0, %k2}";
6099
      else
6100
        return "add{b}\t{%2, %0|%0, %2}";
6101
    }
6102
}
6103
  [(set (attr "type")
6104
     (if_then_else (eq_attr "alternative" "3")
6105
        (const_string "lea")
6106
        (if_then_else (match_operand:QI 2 "incdec_operand" "")
6107
           (const_string "incdec")
6108
           (const_string "alu"))))
6109
   (set_attr "mode" "QI,QI,SI,SI")])
6110
 
6111
(define_insn "*addqi_1"
6112
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6113
        (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6114
                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6115
   (clobber (reg:CC FLAGS_REG))]
6116
  "TARGET_PARTIAL_REG_STALL
6117
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6118
{
6119
  int widen = (which_alternative == 2);
6120
  switch (get_attr_type (insn))
6121
    {
6122
    case TYPE_INCDEC:
6123
      if (operands[2] == const1_rtx)
6124
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6125
      else
6126
        {
6127
          gcc_assert (operands[2] == constm1_rtx);
6128
          return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6129
        }
6130
 
6131
    default:
6132
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6133
         Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6134
      if (GET_CODE (operands[2]) == CONST_INT
6135
          && (INTVAL (operands[2]) == 128
6136
              || (INTVAL (operands[2]) < 0
6137
                  && INTVAL (operands[2]) != -128)))
6138
        {
6139
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6140
          if (widen)
6141
            return "sub{l}\t{%2, %k0|%k0, %2}";
6142
          else
6143
            return "sub{b}\t{%2, %0|%0, %2}";
6144
        }
6145
      if (widen)
6146
        return "add{l}\t{%k2, %k0|%k0, %k2}";
6147
      else
6148
        return "add{b}\t{%2, %0|%0, %2}";
6149
    }
6150
}
6151
  [(set (attr "type")
6152
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6153
        (const_string "incdec")
6154
        (const_string "alu")))
6155
   (set_attr "mode" "QI,QI,SI")])
6156
 
6157
(define_insn "*addqi_1_slp"
6158
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6159
        (plus:QI (match_dup 0)
6160
                 (match_operand:QI 1 "general_operand" "qn,qnm")))
6161
   (clobber (reg:CC FLAGS_REG))]
6162
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6163
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6164
{
6165
  switch (get_attr_type (insn))
6166
    {
6167
    case TYPE_INCDEC:
6168
      if (operands[1] == const1_rtx)
6169
        return "inc{b}\t%0";
6170
      else
6171
        {
6172
          gcc_assert (operands[1] == constm1_rtx);
6173
          return "dec{b}\t%0";
6174
        }
6175
 
6176
    default:
6177
      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6178
      if (GET_CODE (operands[1]) == CONST_INT
6179
          && INTVAL (operands[1]) < 0)
6180
        {
6181
          operands[1] = GEN_INT (-INTVAL (operands[1]));
6182
          return "sub{b}\t{%1, %0|%0, %1}";
6183
        }
6184
      return "add{b}\t{%1, %0|%0, %1}";
6185
    }
6186
}
6187
  [(set (attr "type")
6188
     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6189
        (const_string "incdec")
6190
        (const_string "alu1")))
6191
   (set (attr "memory")
6192
     (if_then_else (match_operand 1 "memory_operand" "")
6193
        (const_string "load")
6194
        (const_string "none")))
6195
   (set_attr "mode" "QI")])
6196
 
6197
(define_insn "*addqi_2"
6198
  [(set (reg FLAGS_REG)
6199
        (compare
6200
          (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6201
                   (match_operand:QI 2 "general_operand" "qmni,qni"))
6202
          (const_int 0)))
6203
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6204
        (plus:QI (match_dup 1) (match_dup 2)))]
6205
  "ix86_match_ccmode (insn, CCGOCmode)
6206
   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6207
{
6208
  switch (get_attr_type (insn))
6209
    {
6210
    case TYPE_INCDEC:
6211
      if (operands[2] == const1_rtx)
6212
        return "inc{b}\t%0";
6213
      else
6214
        {
6215
          gcc_assert (operands[2] == constm1_rtx
6216
                      || (GET_CODE (operands[2]) == CONST_INT
6217
                          && INTVAL (operands[2]) == 255));
6218
          return "dec{b}\t%0";
6219
        }
6220
 
6221
    default:
6222
      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6223
      if (GET_CODE (operands[2]) == CONST_INT
6224
          && INTVAL (operands[2]) < 0)
6225
        {
6226
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6227
          return "sub{b}\t{%2, %0|%0, %2}";
6228
        }
6229
      return "add{b}\t{%2, %0|%0, %2}";
6230
    }
6231
}
6232
  [(set (attr "type")
6233
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6234
        (const_string "incdec")
6235
        (const_string "alu")))
6236
   (set_attr "mode" "QI")])
6237
 
6238
(define_insn "*addqi_3"
6239
  [(set (reg FLAGS_REG)
6240
        (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6241
                 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6242
   (clobber (match_scratch:QI 0 "=q"))]
6243
  "ix86_match_ccmode (insn, CCZmode)
6244
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6245
{
6246
  switch (get_attr_type (insn))
6247
    {
6248
    case TYPE_INCDEC:
6249
      if (operands[2] == const1_rtx)
6250
        return "inc{b}\t%0";
6251
      else
6252
        {
6253
          gcc_assert (operands[2] == constm1_rtx
6254
                      || (GET_CODE (operands[2]) == CONST_INT
6255
                          && INTVAL (operands[2]) == 255));
6256
          return "dec{b}\t%0";
6257
        }
6258
 
6259
    default:
6260
      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6261
      if (GET_CODE (operands[2]) == CONST_INT
6262
          && INTVAL (operands[2]) < 0)
6263
        {
6264
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6265
          return "sub{b}\t{%2, %0|%0, %2}";
6266
        }
6267
      return "add{b}\t{%2, %0|%0, %2}";
6268
    }
6269
}
6270
  [(set (attr "type")
6271
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272
        (const_string "incdec")
6273
        (const_string "alu")))
6274
   (set_attr "mode" "QI")])
6275
 
6276
; See comments above addsi_4 for details.
6277
(define_insn "*addqi_4"
6278
  [(set (reg FLAGS_REG)
6279
        (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6280
                 (match_operand:QI 2 "const_int_operand" "n")))
6281
   (clobber (match_scratch:QI 0 "=qm"))]
6282
  "ix86_match_ccmode (insn, CCGCmode)
6283
   && (INTVAL (operands[2]) & 0xff) != 0x80"
6284
{
6285
  switch (get_attr_type (insn))
6286
    {
6287
    case TYPE_INCDEC:
6288
      if (operands[2] == constm1_rtx
6289
          || (GET_CODE (operands[2]) == CONST_INT
6290
              && INTVAL (operands[2]) == 255))
6291
        return "inc{b}\t%0";
6292
      else
6293
        {
6294
          gcc_assert (operands[2] == const1_rtx);
6295
          return "dec{b}\t%0";
6296
        }
6297
 
6298
    default:
6299
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300
      if (INTVAL (operands[2]) < 0)
6301
        {
6302
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6303
          return "add{b}\t{%2, %0|%0, %2}";
6304
        }
6305
      return "sub{b}\t{%2, %0|%0, %2}";
6306
    }
6307
}
6308
  [(set (attr "type")
6309
     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6310
        (const_string "incdec")
6311
        (const_string "alu")))
6312
   (set_attr "mode" "QI")])
6313
 
6314
 
6315
(define_insn "*addqi_5"
6316
  [(set (reg FLAGS_REG)
6317
        (compare
6318
          (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6319
                   (match_operand:QI 2 "general_operand" "qmni"))
6320
          (const_int 0)))
6321
   (clobber (match_scratch:QI 0 "=q"))]
6322
  "ix86_match_ccmode (insn, CCGOCmode)
6323
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6324
{
6325
  switch (get_attr_type (insn))
6326
    {
6327
    case TYPE_INCDEC:
6328
      if (operands[2] == const1_rtx)
6329
        return "inc{b}\t%0";
6330
      else
6331
        {
6332
          gcc_assert (operands[2] == constm1_rtx
6333
                      || (GET_CODE (operands[2]) == CONST_INT
6334
                          && INTVAL (operands[2]) == 255));
6335
          return "dec{b}\t%0";
6336
        }
6337
 
6338
    default:
6339
      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6340
      if (GET_CODE (operands[2]) == CONST_INT
6341
          && INTVAL (operands[2]) < 0)
6342
        {
6343
          operands[2] = GEN_INT (-INTVAL (operands[2]));
6344
          return "sub{b}\t{%2, %0|%0, %2}";
6345
        }
6346
      return "add{b}\t{%2, %0|%0, %2}";
6347
    }
6348
}
6349
  [(set (attr "type")
6350
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6351
        (const_string "incdec")
6352
        (const_string "alu")))
6353
   (set_attr "mode" "QI")])
6354
 
6355
 
6356
(define_insn "addqi_ext_1"
6357
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6358
                         (const_int 8)
6359
                         (const_int 8))
6360
        (plus:SI
6361
          (zero_extract:SI
6362
            (match_operand 1 "ext_register_operand" "0")
6363
            (const_int 8)
6364
            (const_int 8))
6365
          (match_operand:QI 2 "general_operand" "Qmn")))
6366
   (clobber (reg:CC FLAGS_REG))]
6367
  "!TARGET_64BIT"
6368
{
6369
  switch (get_attr_type (insn))
6370
    {
6371
    case TYPE_INCDEC:
6372
      if (operands[2] == const1_rtx)
6373
        return "inc{b}\t%h0";
6374
      else
6375
        {
6376
          gcc_assert (operands[2] == constm1_rtx
6377
                      || (GET_CODE (operands[2]) == CONST_INT
6378
                          && INTVAL (operands[2]) == 255));
6379
          return "dec{b}\t%h0";
6380
        }
6381
 
6382
    default:
6383
      return "add{b}\t{%2, %h0|%h0, %2}";
6384
    }
6385
}
6386
  [(set (attr "type")
6387
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6388
        (const_string "incdec")
6389
        (const_string "alu")))
6390
   (set_attr "mode" "QI")])
6391
 
6392
(define_insn "*addqi_ext_1_rex64"
6393
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394
                         (const_int 8)
6395
                         (const_int 8))
6396
        (plus:SI
6397
          (zero_extract:SI
6398
            (match_operand 1 "ext_register_operand" "0")
6399
            (const_int 8)
6400
            (const_int 8))
6401
          (match_operand:QI 2 "nonmemory_operand" "Qn")))
6402
   (clobber (reg:CC FLAGS_REG))]
6403
  "TARGET_64BIT"
6404
{
6405
  switch (get_attr_type (insn))
6406
    {
6407
    case TYPE_INCDEC:
6408
      if (operands[2] == const1_rtx)
6409
        return "inc{b}\t%h0";
6410
      else
6411
        {
6412
          gcc_assert (operands[2] == constm1_rtx
6413
                      || (GET_CODE (operands[2]) == CONST_INT
6414
                          && INTVAL (operands[2]) == 255));
6415
          return "dec{b}\t%h0";
6416
        }
6417
 
6418
    default:
6419
      return "add{b}\t{%2, %h0|%h0, %2}";
6420
    }
6421
}
6422
  [(set (attr "type")
6423
     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424
        (const_string "incdec")
6425
        (const_string "alu")))
6426
   (set_attr "mode" "QI")])
6427
 
6428
(define_insn "*addqi_ext_2"
6429
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6430
                         (const_int 8)
6431
                         (const_int 8))
6432
        (plus:SI
6433
          (zero_extract:SI
6434
            (match_operand 1 "ext_register_operand" "%0")
6435
            (const_int 8)
6436
            (const_int 8))
6437
          (zero_extract:SI
6438
            (match_operand 2 "ext_register_operand" "Q")
6439
            (const_int 8)
6440
            (const_int 8))))
6441
   (clobber (reg:CC FLAGS_REG))]
6442
  ""
6443
  "add{b}\t{%h2, %h0|%h0, %h2}"
6444
  [(set_attr "type" "alu")
6445
   (set_attr "mode" "QI")])
6446
 
6447
;; The patterns that match these are at the end of this file.
6448
 
6449
(define_expand "addxf3"
6450
  [(set (match_operand:XF 0 "register_operand" "")
6451
        (plus:XF (match_operand:XF 1 "register_operand" "")
6452
                 (match_operand:XF 2 "register_operand" "")))]
6453
  "TARGET_80387"
6454
  "")
6455
 
6456
(define_expand "adddf3"
6457
  [(set (match_operand:DF 0 "register_operand" "")
6458
        (plus:DF (match_operand:DF 1 "register_operand" "")
6459
                 (match_operand:DF 2 "nonimmediate_operand" "")))]
6460
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6461
  "")
6462
 
6463
(define_expand "addsf3"
6464
  [(set (match_operand:SF 0 "register_operand" "")
6465
        (plus:SF (match_operand:SF 1 "register_operand" "")
6466
                 (match_operand:SF 2 "nonimmediate_operand" "")))]
6467
  "TARGET_80387 || TARGET_SSE_MATH"
6468
  "")
6469
 
6470
;; Subtract instructions
6471
 
6472
;; %%% splits for subditi3
6473
 
6474
(define_expand "subti3"
6475
  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6476
                   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6477
                             (match_operand:TI 2 "x86_64_general_operand" "")))
6478
              (clobber (reg:CC FLAGS_REG))])]
6479
  "TARGET_64BIT"
6480
  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6481
 
6482
(define_insn "*subti3_1"
6483
  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6484
        (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6485
                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6486
   (clobber (reg:CC FLAGS_REG))]
6487
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6488
  "#")
6489
 
6490
(define_split
6491
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492
        (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493
                  (match_operand:TI 2 "x86_64_general_operand" "")))
6494
   (clobber (reg:CC FLAGS_REG))]
6495
  "TARGET_64BIT && reload_completed"
6496
  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6497
              (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6498
   (parallel [(set (match_dup 3)
6499
                   (minus:DI (match_dup 4)
6500
                             (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6501
                                      (match_dup 5))))
6502
              (clobber (reg:CC FLAGS_REG))])]
6503
  "split_ti (operands+0, 1, operands+0, operands+3);
6504
   split_ti (operands+1, 1, operands+1, operands+4);
6505
   split_ti (operands+2, 1, operands+2, operands+5);")
6506
 
6507
;; %%% splits for subsidi3
6508
 
6509
(define_expand "subdi3"
6510
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6511
                   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6512
                             (match_operand:DI 2 "x86_64_general_operand" "")))
6513
              (clobber (reg:CC FLAGS_REG))])]
6514
  ""
6515
  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6516
 
6517
(define_insn "*subdi3_1"
6518
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6519
        (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6520
                  (match_operand:DI 2 "general_operand" "roiF,riF")))
6521
   (clobber (reg:CC FLAGS_REG))]
6522
  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6523
  "#")
6524
 
6525
(define_split
6526
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527
        (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528
                  (match_operand:DI 2 "general_operand" "")))
6529
   (clobber (reg:CC FLAGS_REG))]
6530
  "!TARGET_64BIT && reload_completed"
6531
  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6532
              (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6533
   (parallel [(set (match_dup 3)
6534
                   (minus:SI (match_dup 4)
6535
                             (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6536
                                      (match_dup 5))))
6537
              (clobber (reg:CC FLAGS_REG))])]
6538
  "split_di (operands+0, 1, operands+0, operands+3);
6539
   split_di (operands+1, 1, operands+1, operands+4);
6540
   split_di (operands+2, 1, operands+2, operands+5);")
6541
 
6542
(define_insn "subdi3_carry_rex64"
6543
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6544
          (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6545
            (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6546
               (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6547
   (clobber (reg:CC FLAGS_REG))]
6548
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6549
  "sbb{q}\t{%2, %0|%0, %2}"
6550
  [(set_attr "type" "alu")
6551
   (set_attr "pent_pair" "pu")
6552
   (set_attr "mode" "DI")])
6553
 
6554
(define_insn "*subdi_1_rex64"
6555
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6556
        (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6557
                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6558
   (clobber (reg:CC FLAGS_REG))]
6559
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6560
  "sub{q}\t{%2, %0|%0, %2}"
6561
  [(set_attr "type" "alu")
6562
   (set_attr "mode" "DI")])
6563
 
6564
(define_insn "*subdi_2_rex64"
6565
  [(set (reg FLAGS_REG)
6566
        (compare
6567
          (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6568
                    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6569
          (const_int 0)))
6570
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6571
        (minus:DI (match_dup 1) (match_dup 2)))]
6572
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6573
   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6574
  "sub{q}\t{%2, %0|%0, %2}"
6575
  [(set_attr "type" "alu")
6576
   (set_attr "mode" "DI")])
6577
 
6578
(define_insn "*subdi_3_rex63"
6579
  [(set (reg FLAGS_REG)
6580
        (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6581
                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6582
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6583
        (minus:DI (match_dup 1) (match_dup 2)))]
6584
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6585
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6586
  "sub{q}\t{%2, %0|%0, %2}"
6587
  [(set_attr "type" "alu")
6588
   (set_attr "mode" "DI")])
6589
 
6590
(define_insn "subqi3_carry"
6591
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6592
          (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6593
            (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6594
               (match_operand:QI 2 "general_operand" "qi,qm"))))
6595
   (clobber (reg:CC FLAGS_REG))]
6596
  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6597
  "sbb{b}\t{%2, %0|%0, %2}"
6598
  [(set_attr "type" "alu")
6599
   (set_attr "pent_pair" "pu")
6600
   (set_attr "mode" "QI")])
6601
 
6602
(define_insn "subhi3_carry"
6603
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6604
          (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6605
            (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6606
               (match_operand:HI 2 "general_operand" "ri,rm"))))
6607
   (clobber (reg:CC FLAGS_REG))]
6608
  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6609
  "sbb{w}\t{%2, %0|%0, %2}"
6610
  [(set_attr "type" "alu")
6611
   (set_attr "pent_pair" "pu")
6612
   (set_attr "mode" "HI")])
6613
 
6614
(define_insn "subsi3_carry"
6615
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6616
          (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6617
            (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6618
               (match_operand:SI 2 "general_operand" "ri,rm"))))
6619
   (clobber (reg:CC FLAGS_REG))]
6620
  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621
  "sbb{l}\t{%2, %0|%0, %2}"
6622
  [(set_attr "type" "alu")
6623
   (set_attr "pent_pair" "pu")
6624
   (set_attr "mode" "SI")])
6625
 
6626
(define_insn "subsi3_carry_zext"
6627
  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6628
          (zero_extend:DI
6629
            (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6630
              (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6631
                 (match_operand:SI 2 "general_operand" "ri,rm")))))
6632
   (clobber (reg:CC FLAGS_REG))]
6633
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6634
  "sbb{l}\t{%2, %k0|%k0, %2}"
6635
  [(set_attr "type" "alu")
6636
   (set_attr "pent_pair" "pu")
6637
   (set_attr "mode" "SI")])
6638
 
6639
(define_expand "subsi3"
6640
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6641
                   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6642
                             (match_operand:SI 2 "general_operand" "")))
6643
              (clobber (reg:CC FLAGS_REG))])]
6644
  ""
6645
  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6646
 
6647
(define_insn "*subsi_1"
6648
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6649
        (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6650
                  (match_operand:SI 2 "general_operand" "ri,rm")))
6651
   (clobber (reg:CC FLAGS_REG))]
6652
  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6653
  "sub{l}\t{%2, %0|%0, %2}"
6654
  [(set_attr "type" "alu")
6655
   (set_attr "mode" "SI")])
6656
 
6657
(define_insn "*subsi_1_zext"
6658
  [(set (match_operand:DI 0 "register_operand" "=r")
6659
        (zero_extend:DI
6660
          (minus:SI (match_operand:SI 1 "register_operand" "0")
6661
                    (match_operand:SI 2 "general_operand" "rim"))))
6662
   (clobber (reg:CC FLAGS_REG))]
6663
  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6664
  "sub{l}\t{%2, %k0|%k0, %2}"
6665
  [(set_attr "type" "alu")
6666
   (set_attr "mode" "SI")])
6667
 
6668
(define_insn "*subsi_2"
6669
  [(set (reg FLAGS_REG)
6670
        (compare
6671
          (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672
                    (match_operand:SI 2 "general_operand" "ri,rm"))
6673
          (const_int 0)))
6674
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675
        (minus:SI (match_dup 1) (match_dup 2)))]
6676
  "ix86_match_ccmode (insn, CCGOCmode)
6677
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678
  "sub{l}\t{%2, %0|%0, %2}"
6679
  [(set_attr "type" "alu")
6680
   (set_attr "mode" "SI")])
6681
 
6682
(define_insn "*subsi_2_zext"
6683
  [(set (reg FLAGS_REG)
6684
        (compare
6685
          (minus:SI (match_operand:SI 1 "register_operand" "0")
6686
                    (match_operand:SI 2 "general_operand" "rim"))
6687
          (const_int 0)))
6688
   (set (match_operand:DI 0 "register_operand" "=r")
6689
        (zero_extend:DI
6690
          (minus:SI (match_dup 1)
6691
                    (match_dup 2))))]
6692
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6693
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694
  "sub{l}\t{%2, %k0|%k0, %2}"
6695
  [(set_attr "type" "alu")
6696
   (set_attr "mode" "SI")])
6697
 
6698
(define_insn "*subsi_3"
6699
  [(set (reg FLAGS_REG)
6700
        (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6701
                 (match_operand:SI 2 "general_operand" "ri,rm")))
6702
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6703
        (minus:SI (match_dup 1) (match_dup 2)))]
6704
  "ix86_match_ccmode (insn, CCmode)
6705
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6706
  "sub{l}\t{%2, %0|%0, %2}"
6707
  [(set_attr "type" "alu")
6708
   (set_attr "mode" "SI")])
6709
 
6710
(define_insn "*subsi_3_zext"
6711
  [(set (reg FLAGS_REG)
6712
        (compare (match_operand:SI 1 "register_operand" "0")
6713
                 (match_operand:SI 2 "general_operand" "rim")))
6714
   (set (match_operand:DI 0 "register_operand" "=r")
6715
        (zero_extend:DI
6716
          (minus:SI (match_dup 1)
6717
                    (match_dup 2))))]
6718
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6719
   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720
  "sub{l}\t{%2, %1|%1, %2}"
6721
  [(set_attr "type" "alu")
6722
   (set_attr "mode" "DI")])
6723
 
6724
(define_expand "subhi3"
6725
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6726
                   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6727
                             (match_operand:HI 2 "general_operand" "")))
6728
              (clobber (reg:CC FLAGS_REG))])]
6729
  "TARGET_HIMODE_MATH"
6730
  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6731
 
6732
(define_insn "*subhi_1"
6733
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6734
        (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735
                  (match_operand:HI 2 "general_operand" "ri,rm")))
6736
   (clobber (reg:CC FLAGS_REG))]
6737
  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6738
  "sub{w}\t{%2, %0|%0, %2}"
6739
  [(set_attr "type" "alu")
6740
   (set_attr "mode" "HI")])
6741
 
6742
(define_insn "*subhi_2"
6743
  [(set (reg FLAGS_REG)
6744
        (compare
6745
          (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6746
                    (match_operand:HI 2 "general_operand" "ri,rm"))
6747
          (const_int 0)))
6748
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6749
        (minus:HI (match_dup 1) (match_dup 2)))]
6750
  "ix86_match_ccmode (insn, CCGOCmode)
6751
   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6752
  "sub{w}\t{%2, %0|%0, %2}"
6753
  [(set_attr "type" "alu")
6754
   (set_attr "mode" "HI")])
6755
 
6756
(define_insn "*subhi_3"
6757
  [(set (reg FLAGS_REG)
6758
        (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6759
                 (match_operand:HI 2 "general_operand" "ri,rm")))
6760
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6761
        (minus:HI (match_dup 1) (match_dup 2)))]
6762
  "ix86_match_ccmode (insn, CCmode)
6763
   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6764
  "sub{w}\t{%2, %0|%0, %2}"
6765
  [(set_attr "type" "alu")
6766
   (set_attr "mode" "HI")])
6767
 
6768
(define_expand "subqi3"
6769
  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6770
                   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6771
                             (match_operand:QI 2 "general_operand" "")))
6772
              (clobber (reg:CC FLAGS_REG))])]
6773
  "TARGET_QIMODE_MATH"
6774
  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6775
 
6776
(define_insn "*subqi_1"
6777
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6778
        (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6779
                  (match_operand:QI 2 "general_operand" "qn,qmn")))
6780
   (clobber (reg:CC FLAGS_REG))]
6781
  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6782
  "sub{b}\t{%2, %0|%0, %2}"
6783
  [(set_attr "type" "alu")
6784
   (set_attr "mode" "QI")])
6785
 
6786
(define_insn "*subqi_1_slp"
6787
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6788
        (minus:QI (match_dup 0)
6789
                  (match_operand:QI 1 "general_operand" "qn,qmn")))
6790
   (clobber (reg:CC FLAGS_REG))]
6791
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6792
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6793
  "sub{b}\t{%1, %0|%0, %1}"
6794
  [(set_attr "type" "alu1")
6795
   (set_attr "mode" "QI")])
6796
 
6797
(define_insn "*subqi_2"
6798
  [(set (reg FLAGS_REG)
6799
        (compare
6800
          (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801
                    (match_operand:QI 2 "general_operand" "qi,qm"))
6802
          (const_int 0)))
6803
   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6804
        (minus:HI (match_dup 1) (match_dup 2)))]
6805
  "ix86_match_ccmode (insn, CCGOCmode)
6806
   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6807
  "sub{b}\t{%2, %0|%0, %2}"
6808
  [(set_attr "type" "alu")
6809
   (set_attr "mode" "QI")])
6810
 
6811
(define_insn "*subqi_3"
6812
  [(set (reg FLAGS_REG)
6813
        (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6814
                 (match_operand:QI 2 "general_operand" "qi,qm")))
6815
   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6816
        (minus:HI (match_dup 1) (match_dup 2)))]
6817
  "ix86_match_ccmode (insn, CCmode)
6818
   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6819
  "sub{b}\t{%2, %0|%0, %2}"
6820
  [(set_attr "type" "alu")
6821
   (set_attr "mode" "QI")])
6822
 
6823
;; The patterns that match these are at the end of this file.
6824
 
6825
(define_expand "subxf3"
6826
  [(set (match_operand:XF 0 "register_operand" "")
6827
        (minus:XF (match_operand:XF 1 "register_operand" "")
6828
                  (match_operand:XF 2 "register_operand" "")))]
6829
  "TARGET_80387"
6830
  "")
6831
 
6832
(define_expand "subdf3"
6833
  [(set (match_operand:DF 0 "register_operand" "")
6834
        (minus:DF (match_operand:DF 1 "register_operand" "")
6835
                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6836
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6837
  "")
6838
 
6839
(define_expand "subsf3"
6840
  [(set (match_operand:SF 0 "register_operand" "")
6841
        (minus:SF (match_operand:SF 1 "register_operand" "")
6842
                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6843
  "TARGET_80387 || TARGET_SSE_MATH"
6844
  "")
6845
 
6846
;; Multiply instructions
6847
 
6848
(define_expand "muldi3"
6849
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6850
                   (mult:DI (match_operand:DI 1 "register_operand" "")
6851
                            (match_operand:DI 2 "x86_64_general_operand" "")))
6852
              (clobber (reg:CC FLAGS_REG))])]
6853
  "TARGET_64BIT"
6854
  "")
6855
 
6856
(define_insn "*muldi3_1_rex64"
6857
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6858
        (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6859
                 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6860
   (clobber (reg:CC FLAGS_REG))]
6861
  "TARGET_64BIT
6862
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6863
  "@
6864
   imul{q}\t{%2, %1, %0|%0, %1, %2}
6865
   imul{q}\t{%2, %1, %0|%0, %1, %2}
6866
   imul{q}\t{%2, %0|%0, %2}"
6867
  [(set_attr "type" "imul")
6868
   (set_attr "prefix_0f" "0,0,1")
6869
   (set (attr "athlon_decode")
6870
        (cond [(eq_attr "cpu" "athlon")
6871
                  (const_string "vector")
6872
               (eq_attr "alternative" "1")
6873
                  (const_string "vector")
6874
               (and (eq_attr "alternative" "2")
6875
                    (match_operand 1 "memory_operand" ""))
6876
                  (const_string "vector")]
6877
              (const_string "direct")))
6878
   (set_attr "mode" "DI")])
6879
 
6880
(define_expand "mulsi3"
6881
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6882
                   (mult:SI (match_operand:SI 1 "register_operand" "")
6883
                            (match_operand:SI 2 "general_operand" "")))
6884
              (clobber (reg:CC FLAGS_REG))])]
6885
  ""
6886
  "")
6887
 
6888
(define_insn "*mulsi3_1"
6889
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6890
        (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891
                 (match_operand:SI 2 "general_operand" "K,i,mr")))
6892
   (clobber (reg:CC FLAGS_REG))]
6893
  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6894
  "@
6895
   imul{l}\t{%2, %1, %0|%0, %1, %2}
6896
   imul{l}\t{%2, %1, %0|%0, %1, %2}
6897
   imul{l}\t{%2, %0|%0, %2}"
6898
  [(set_attr "type" "imul")
6899
   (set_attr "prefix_0f" "0,0,1")
6900
   (set (attr "athlon_decode")
6901
        (cond [(eq_attr "cpu" "athlon")
6902
                  (const_string "vector")
6903
               (eq_attr "alternative" "1")
6904
                  (const_string "vector")
6905
               (and (eq_attr "alternative" "2")
6906
                    (match_operand 1 "memory_operand" ""))
6907
                  (const_string "vector")]
6908
              (const_string "direct")))
6909
   (set_attr "mode" "SI")])
6910
 
6911
(define_insn "*mulsi3_1_zext"
6912
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913
        (zero_extend:DI
6914
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6915
                   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6916
   (clobber (reg:CC FLAGS_REG))]
6917
  "TARGET_64BIT
6918
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919
  "@
6920
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921
   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922
   imul{l}\t{%2, %k0|%k0, %2}"
6923
  [(set_attr "type" "imul")
6924
   (set_attr "prefix_0f" "0,0,1")
6925
   (set (attr "athlon_decode")
6926
        (cond [(eq_attr "cpu" "athlon")
6927
                  (const_string "vector")
6928
               (eq_attr "alternative" "1")
6929
                  (const_string "vector")
6930
               (and (eq_attr "alternative" "2")
6931
                    (match_operand 1 "memory_operand" ""))
6932
                  (const_string "vector")]
6933
              (const_string "direct")))
6934
   (set_attr "mode" "SI")])
6935
 
6936
(define_expand "mulhi3"
6937
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6938
                   (mult:HI (match_operand:HI 1 "register_operand" "")
6939
                            (match_operand:HI 2 "general_operand" "")))
6940
              (clobber (reg:CC FLAGS_REG))])]
6941
  "TARGET_HIMODE_MATH"
6942
  "")
6943
 
6944
(define_insn "*mulhi3_1"
6945
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6946
        (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6947
                 (match_operand:HI 2 "general_operand" "K,i,mr")))
6948
   (clobber (reg:CC FLAGS_REG))]
6949
  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6950
  "@
6951
   imul{w}\t{%2, %1, %0|%0, %1, %2}
6952
   imul{w}\t{%2, %1, %0|%0, %1, %2}
6953
   imul{w}\t{%2, %0|%0, %2}"
6954
  [(set_attr "type" "imul")
6955
   (set_attr "prefix_0f" "0,0,1")
6956
   (set (attr "athlon_decode")
6957
        (cond [(eq_attr "cpu" "athlon")
6958
                  (const_string "vector")
6959
               (eq_attr "alternative" "1,2")
6960
                  (const_string "vector")]
6961
              (const_string "direct")))
6962
   (set_attr "mode" "HI")])
6963
 
6964
(define_expand "mulqi3"
6965
  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6966
                   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6967
                            (match_operand:QI 2 "register_operand" "")))
6968
              (clobber (reg:CC FLAGS_REG))])]
6969
  "TARGET_QIMODE_MATH"
6970
  "")
6971
 
6972
(define_insn "*mulqi3_1"
6973
  [(set (match_operand:QI 0 "register_operand" "=a")
6974
        (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6975
                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6976
   (clobber (reg:CC FLAGS_REG))]
6977
  "TARGET_QIMODE_MATH
6978
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6979
  "mul{b}\t%2"
6980
  [(set_attr "type" "imul")
6981
   (set_attr "length_immediate" "0")
6982
   (set (attr "athlon_decode")
6983
     (if_then_else (eq_attr "cpu" "athlon")
6984
        (const_string "vector")
6985
        (const_string "direct")))
6986
   (set_attr "mode" "QI")])
6987
 
6988
(define_expand "umulqihi3"
6989
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6990
                   (mult:HI (zero_extend:HI
6991
                              (match_operand:QI 1 "nonimmediate_operand" ""))
6992
                            (zero_extend:HI
6993
                              (match_operand:QI 2 "register_operand" ""))))
6994
              (clobber (reg:CC FLAGS_REG))])]
6995
  "TARGET_QIMODE_MATH"
6996
  "")
6997
 
6998
(define_insn "*umulqihi3_1"
6999
  [(set (match_operand:HI 0 "register_operand" "=a")
7000
        (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7001
                 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7002
   (clobber (reg:CC FLAGS_REG))]
7003
  "TARGET_QIMODE_MATH
7004
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005
  "mul{b}\t%2"
7006
  [(set_attr "type" "imul")
7007
   (set_attr "length_immediate" "0")
7008
   (set (attr "athlon_decode")
7009
     (if_then_else (eq_attr "cpu" "athlon")
7010
        (const_string "vector")
7011
        (const_string "direct")))
7012
   (set_attr "mode" "QI")])
7013
 
7014
(define_expand "mulqihi3"
7015
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016
                   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7017
                            (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7018
              (clobber (reg:CC FLAGS_REG))])]
7019
  "TARGET_QIMODE_MATH"
7020
  "")
7021
 
7022
(define_insn "*mulqihi3_insn"
7023
  [(set (match_operand:HI 0 "register_operand" "=a")
7024
        (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7025
                 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7026
   (clobber (reg:CC FLAGS_REG))]
7027
  "TARGET_QIMODE_MATH
7028
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7029
  "imul{b}\t%2"
7030
  [(set_attr "type" "imul")
7031
   (set_attr "length_immediate" "0")
7032
   (set (attr "athlon_decode")
7033
     (if_then_else (eq_attr "cpu" "athlon")
7034
        (const_string "vector")
7035
        (const_string "direct")))
7036
   (set_attr "mode" "QI")])
7037
 
7038
(define_expand "umulditi3"
7039
  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7040
                   (mult:TI (zero_extend:TI
7041
                              (match_operand:DI 1 "nonimmediate_operand" ""))
7042
                            (zero_extend:TI
7043
                              (match_operand:DI 2 "register_operand" ""))))
7044
              (clobber (reg:CC FLAGS_REG))])]
7045
  "TARGET_64BIT"
7046
  "")
7047
 
7048
(define_insn "*umulditi3_insn"
7049
  [(set (match_operand:TI 0 "register_operand" "=A")
7050
        (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7051
                 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7052
   (clobber (reg:CC FLAGS_REG))]
7053
  "TARGET_64BIT
7054
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055
  "mul{q}\t%2"
7056
  [(set_attr "type" "imul")
7057
   (set_attr "length_immediate" "0")
7058
   (set (attr "athlon_decode")
7059
     (if_then_else (eq_attr "cpu" "athlon")
7060
        (const_string "vector")
7061
        (const_string "double")))
7062
   (set_attr "mode" "DI")])
7063
 
7064
;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7065
(define_expand "umulsidi3"
7066
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7067
                   (mult:DI (zero_extend:DI
7068
                              (match_operand:SI 1 "nonimmediate_operand" ""))
7069
                            (zero_extend:DI
7070
                              (match_operand:SI 2 "register_operand" ""))))
7071
              (clobber (reg:CC FLAGS_REG))])]
7072
  "!TARGET_64BIT"
7073
  "")
7074
 
7075
(define_insn "*umulsidi3_insn"
7076
  [(set (match_operand:DI 0 "register_operand" "=A")
7077
        (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7078
                 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7079
   (clobber (reg:CC FLAGS_REG))]
7080
  "!TARGET_64BIT
7081
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082
  "mul{l}\t%2"
7083
  [(set_attr "type" "imul")
7084
   (set_attr "length_immediate" "0")
7085
   (set (attr "athlon_decode")
7086
     (if_then_else (eq_attr "cpu" "athlon")
7087
        (const_string "vector")
7088
        (const_string "double")))
7089
   (set_attr "mode" "SI")])
7090
 
7091
(define_expand "mulditi3"
7092
  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7093
                   (mult:TI (sign_extend:TI
7094
                              (match_operand:DI 1 "nonimmediate_operand" ""))
7095
                            (sign_extend:TI
7096
                              (match_operand:DI 2 "register_operand" ""))))
7097
              (clobber (reg:CC FLAGS_REG))])]
7098
  "TARGET_64BIT"
7099
  "")
7100
 
7101
(define_insn "*mulditi3_insn"
7102
  [(set (match_operand:TI 0 "register_operand" "=A")
7103
        (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7104
                 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7105
   (clobber (reg:CC FLAGS_REG))]
7106
  "TARGET_64BIT
7107
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108
  "imul{q}\t%2"
7109
  [(set_attr "type" "imul")
7110
   (set_attr "length_immediate" "0")
7111
   (set (attr "athlon_decode")
7112
     (if_then_else (eq_attr "cpu" "athlon")
7113
        (const_string "vector")
7114
        (const_string "double")))
7115
   (set_attr "mode" "DI")])
7116
 
7117
(define_expand "mulsidi3"
7118
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7119
                   (mult:DI (sign_extend:DI
7120
                              (match_operand:SI 1 "nonimmediate_operand" ""))
7121
                            (sign_extend:DI
7122
                              (match_operand:SI 2 "register_operand" ""))))
7123
              (clobber (reg:CC FLAGS_REG))])]
7124
  "!TARGET_64BIT"
7125
  "")
7126
 
7127
(define_insn "*mulsidi3_insn"
7128
  [(set (match_operand:DI 0 "register_operand" "=A")
7129
        (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7130
                 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7131
   (clobber (reg:CC FLAGS_REG))]
7132
  "!TARGET_64BIT
7133
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7134
  "imul{l}\t%2"
7135
  [(set_attr "type" "imul")
7136
   (set_attr "length_immediate" "0")
7137
   (set (attr "athlon_decode")
7138
     (if_then_else (eq_attr "cpu" "athlon")
7139
        (const_string "vector")
7140
        (const_string "double")))
7141
   (set_attr "mode" "SI")])
7142
 
7143
(define_expand "umuldi3_highpart"
7144
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145
                   (truncate:DI
7146
                     (lshiftrt:TI
7147
                       (mult:TI (zero_extend:TI
7148
                                  (match_operand:DI 1 "nonimmediate_operand" ""))
7149
                                (zero_extend:TI
7150
                                  (match_operand:DI 2 "register_operand" "")))
7151
                       (const_int 64))))
7152
              (clobber (match_scratch:DI 3 ""))
7153
              (clobber (reg:CC FLAGS_REG))])]
7154
  "TARGET_64BIT"
7155
  "")
7156
 
7157
(define_insn "*umuldi3_highpart_rex64"
7158
  [(set (match_operand:DI 0 "register_operand" "=d")
7159
        (truncate:DI
7160
          (lshiftrt:TI
7161
            (mult:TI (zero_extend:TI
7162
                       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7163
                     (zero_extend:TI
7164
                       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7165
            (const_int 64))))
7166
   (clobber (match_scratch:DI 3 "=1"))
7167
   (clobber (reg:CC FLAGS_REG))]
7168
  "TARGET_64BIT
7169
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7170
  "mul{q}\t%2"
7171
  [(set_attr "type" "imul")
7172
   (set_attr "length_immediate" "0")
7173
   (set (attr "athlon_decode")
7174
     (if_then_else (eq_attr "cpu" "athlon")
7175
        (const_string "vector")
7176
        (const_string "double")))
7177
   (set_attr "mode" "DI")])
7178
 
7179
(define_expand "umulsi3_highpart"
7180
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7181
                   (truncate:SI
7182
                     (lshiftrt:DI
7183
                       (mult:DI (zero_extend:DI
7184
                                  (match_operand:SI 1 "nonimmediate_operand" ""))
7185
                                (zero_extend:DI
7186
                                  (match_operand:SI 2 "register_operand" "")))
7187
                       (const_int 32))))
7188
              (clobber (match_scratch:SI 3 ""))
7189
              (clobber (reg:CC FLAGS_REG))])]
7190
  ""
7191
  "")
7192
 
7193
(define_insn "*umulsi3_highpart_insn"
7194
  [(set (match_operand:SI 0 "register_operand" "=d")
7195
        (truncate:SI
7196
          (lshiftrt:DI
7197
            (mult:DI (zero_extend:DI
7198
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7199
                     (zero_extend:DI
7200
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7201
            (const_int 32))))
7202
   (clobber (match_scratch:SI 3 "=1"))
7203
   (clobber (reg:CC FLAGS_REG))]
7204
  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7205
  "mul{l}\t%2"
7206
  [(set_attr "type" "imul")
7207
   (set_attr "length_immediate" "0")
7208
   (set (attr "athlon_decode")
7209
     (if_then_else (eq_attr "cpu" "athlon")
7210
        (const_string "vector")
7211
        (const_string "double")))
7212
   (set_attr "mode" "SI")])
7213
 
7214
(define_insn "*umulsi3_highpart_zext"
7215
  [(set (match_operand:DI 0 "register_operand" "=d")
7216
        (zero_extend:DI (truncate:SI
7217
          (lshiftrt:DI
7218
            (mult:DI (zero_extend:DI
7219
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7220
                     (zero_extend:DI
7221
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7222
            (const_int 32)))))
7223
   (clobber (match_scratch:SI 3 "=1"))
7224
   (clobber (reg:CC FLAGS_REG))]
7225
  "TARGET_64BIT
7226
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227
  "mul{l}\t%2"
7228
  [(set_attr "type" "imul")
7229
   (set_attr "length_immediate" "0")
7230
   (set (attr "athlon_decode")
7231
     (if_then_else (eq_attr "cpu" "athlon")
7232
        (const_string "vector")
7233
        (const_string "double")))
7234
   (set_attr "mode" "SI")])
7235
 
7236
(define_expand "smuldi3_highpart"
7237
  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7238
                   (truncate:DI
7239
                     (lshiftrt:TI
7240
                       (mult:TI (sign_extend:TI
7241
                                  (match_operand:DI 1 "nonimmediate_operand" ""))
7242
                                (sign_extend:TI
7243
                                  (match_operand:DI 2 "register_operand" "")))
7244
                       (const_int 64))))
7245
              (clobber (match_scratch:DI 3 ""))
7246
              (clobber (reg:CC FLAGS_REG))])]
7247
  "TARGET_64BIT"
7248
  "")
7249
 
7250
(define_insn "*smuldi3_highpart_rex64"
7251
  [(set (match_operand:DI 0 "register_operand" "=d")
7252
        (truncate:DI
7253
          (lshiftrt:TI
7254
            (mult:TI (sign_extend:TI
7255
                       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7256
                     (sign_extend:TI
7257
                       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7258
            (const_int 64))))
7259
   (clobber (match_scratch:DI 3 "=1"))
7260
   (clobber (reg:CC FLAGS_REG))]
7261
  "TARGET_64BIT
7262
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7263
  "imul{q}\t%2"
7264
  [(set_attr "type" "imul")
7265
   (set (attr "athlon_decode")
7266
     (if_then_else (eq_attr "cpu" "athlon")
7267
        (const_string "vector")
7268
        (const_string "double")))
7269
   (set_attr "mode" "DI")])
7270
 
7271
(define_expand "smulsi3_highpart"
7272
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7273
                   (truncate:SI
7274
                     (lshiftrt:DI
7275
                       (mult:DI (sign_extend:DI
7276
                                  (match_operand:SI 1 "nonimmediate_operand" ""))
7277
                                (sign_extend:DI
7278
                                  (match_operand:SI 2 "register_operand" "")))
7279
                       (const_int 32))))
7280
              (clobber (match_scratch:SI 3 ""))
7281
              (clobber (reg:CC FLAGS_REG))])]
7282
  ""
7283
  "")
7284
 
7285
(define_insn "*smulsi3_highpart_insn"
7286
  [(set (match_operand:SI 0 "register_operand" "=d")
7287
        (truncate:SI
7288
          (lshiftrt:DI
7289
            (mult:DI (sign_extend:DI
7290
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7291
                     (sign_extend:DI
7292
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7293
            (const_int 32))))
7294
   (clobber (match_scratch:SI 3 "=1"))
7295
   (clobber (reg:CC FLAGS_REG))]
7296
  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7297
  "imul{l}\t%2"
7298
  [(set_attr "type" "imul")
7299
   (set (attr "athlon_decode")
7300
     (if_then_else (eq_attr "cpu" "athlon")
7301
        (const_string "vector")
7302
        (const_string "double")))
7303
   (set_attr "mode" "SI")])
7304
 
7305
(define_insn "*smulsi3_highpart_zext"
7306
  [(set (match_operand:DI 0 "register_operand" "=d")
7307
        (zero_extend:DI (truncate:SI
7308
          (lshiftrt:DI
7309
            (mult:DI (sign_extend:DI
7310
                       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7311
                     (sign_extend:DI
7312
                       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7313
            (const_int 32)))))
7314
   (clobber (match_scratch:SI 3 "=1"))
7315
   (clobber (reg:CC FLAGS_REG))]
7316
  "TARGET_64BIT
7317
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7318
  "imul{l}\t%2"
7319
  [(set_attr "type" "imul")
7320
   (set (attr "athlon_decode")
7321
     (if_then_else (eq_attr "cpu" "athlon")
7322
        (const_string "vector")
7323
        (const_string "double")))
7324
   (set_attr "mode" "SI")])
7325
 
7326
;; The patterns that match these are at the end of this file.
7327
 
7328
(define_expand "mulxf3"
7329
  [(set (match_operand:XF 0 "register_operand" "")
7330
        (mult:XF (match_operand:XF 1 "register_operand" "")
7331
                 (match_operand:XF 2 "register_operand" "")))]
7332
  "TARGET_80387"
7333
  "")
7334
 
7335
(define_expand "muldf3"
7336
  [(set (match_operand:DF 0 "register_operand" "")
7337
        (mult:DF (match_operand:DF 1 "register_operand" "")
7338
                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7339
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7340
  "")
7341
 
7342
(define_expand "mulsf3"
7343
  [(set (match_operand:SF 0 "register_operand" "")
7344
        (mult:SF (match_operand:SF 1 "register_operand" "")
7345
                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7346
  "TARGET_80387 || TARGET_SSE_MATH"
7347
  "")
7348
 
7349
;; Divide instructions
7350
 
7351
(define_insn "divqi3"
7352
  [(set (match_operand:QI 0 "register_operand" "=a")
7353
        (div:QI (match_operand:HI 1 "register_operand" "0")
7354
                (match_operand:QI 2 "nonimmediate_operand" "qm")))
7355
   (clobber (reg:CC FLAGS_REG))]
7356
  "TARGET_QIMODE_MATH"
7357
  "idiv{b}\t%2"
7358
  [(set_attr "type" "idiv")
7359
   (set_attr "mode" "QI")])
7360
 
7361
(define_insn "udivqi3"
7362
  [(set (match_operand:QI 0 "register_operand" "=a")
7363
        (udiv:QI (match_operand:HI 1 "register_operand" "0")
7364
                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7365
   (clobber (reg:CC FLAGS_REG))]
7366
  "TARGET_QIMODE_MATH"
7367
  "div{b}\t%2"
7368
  [(set_attr "type" "idiv")
7369
   (set_attr "mode" "QI")])
7370
 
7371
;; The patterns that match these are at the end of this file.
7372
 
7373
(define_expand "divxf3"
7374
  [(set (match_operand:XF 0 "register_operand" "")
7375
        (div:XF (match_operand:XF 1 "register_operand" "")
7376
                (match_operand:XF 2 "register_operand" "")))]
7377
  "TARGET_80387"
7378
  "")
7379
 
7380
(define_expand "divdf3"
7381
  [(set (match_operand:DF 0 "register_operand" "")
7382
        (div:DF (match_operand:DF 1 "register_operand" "")
7383
                (match_operand:DF 2 "nonimmediate_operand" "")))]
7384
   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7385
   "")
7386
 
7387
(define_expand "divsf3"
7388
  [(set (match_operand:SF 0 "register_operand" "")
7389
        (div:SF (match_operand:SF 1 "register_operand" "")
7390
                (match_operand:SF 2 "nonimmediate_operand" "")))]
7391
  "TARGET_80387 || TARGET_SSE_MATH"
7392
  "")
7393
 
7394
;; Remainder instructions.
7395
 
7396
(define_expand "divmoddi4"
7397
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7398
                   (div:DI (match_operand:DI 1 "register_operand" "")
7399
                           (match_operand:DI 2 "nonimmediate_operand" "")))
7400
              (set (match_operand:DI 3 "register_operand" "")
7401
                   (mod:DI (match_dup 1) (match_dup 2)))
7402
              (clobber (reg:CC FLAGS_REG))])]
7403
  "TARGET_64BIT"
7404
  "")
7405
 
7406
;; Allow to come the parameter in eax or edx to avoid extra moves.
7407
;; Penalize eax case slightly because it results in worse scheduling
7408
;; of code.
7409
(define_insn "*divmoddi4_nocltd_rex64"
7410
  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7411
        (div:DI (match_operand:DI 2 "register_operand" "1,0")
7412
                (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7413
   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7414
        (mod:DI (match_dup 2) (match_dup 3)))
7415
   (clobber (reg:CC FLAGS_REG))]
7416
  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7417
  "#"
7418
  [(set_attr "type" "multi")])
7419
 
7420
(define_insn "*divmoddi4_cltd_rex64"
7421
  [(set (match_operand:DI 0 "register_operand" "=a")
7422
        (div:DI (match_operand:DI 2 "register_operand" "a")
7423
                (match_operand:DI 3 "nonimmediate_operand" "rm")))
7424
   (set (match_operand:DI 1 "register_operand" "=&d")
7425
        (mod:DI (match_dup 2) (match_dup 3)))
7426
   (clobber (reg:CC FLAGS_REG))]
7427
  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7428
  "#"
7429
  [(set_attr "type" "multi")])
7430
 
7431
(define_insn "*divmoddi_noext_rex64"
7432
  [(set (match_operand:DI 0 "register_operand" "=a")
7433
        (div:DI (match_operand:DI 1 "register_operand" "0")
7434
                (match_operand:DI 2 "nonimmediate_operand" "rm")))
7435
   (set (match_operand:DI 3 "register_operand" "=d")
7436
        (mod:DI (match_dup 1) (match_dup 2)))
7437
   (use (match_operand:DI 4 "register_operand" "3"))
7438
   (clobber (reg:CC FLAGS_REG))]
7439
  "TARGET_64BIT"
7440
  "idiv{q}\t%2"
7441
  [(set_attr "type" "idiv")
7442
   (set_attr "mode" "DI")])
7443
 
7444
(define_split
7445
  [(set (match_operand:DI 0 "register_operand" "")
7446
        (div:DI (match_operand:DI 1 "register_operand" "")
7447
                (match_operand:DI 2 "nonimmediate_operand" "")))
7448
   (set (match_operand:DI 3 "register_operand" "")
7449
        (mod:DI (match_dup 1) (match_dup 2)))
7450
   (clobber (reg:CC FLAGS_REG))]
7451
  "TARGET_64BIT && reload_completed"
7452
  [(parallel [(set (match_dup 3)
7453
                   (ashiftrt:DI (match_dup 4) (const_int 63)))
7454
              (clobber (reg:CC FLAGS_REG))])
7455
   (parallel [(set (match_dup 0)
7456
                   (div:DI (reg:DI 0) (match_dup 2)))
7457
              (set (match_dup 3)
7458
                   (mod:DI (reg:DI 0) (match_dup 2)))
7459
              (use (match_dup 3))
7460
              (clobber (reg:CC FLAGS_REG))])]
7461
{
7462
  /* Avoid use of cltd in favor of a mov+shift.  */
7463
  if (!TARGET_USE_CLTD && !optimize_size)
7464
    {
7465
      if (true_regnum (operands[1]))
7466
        emit_move_insn (operands[0], operands[1]);
7467
      else
7468
        emit_move_insn (operands[3], operands[1]);
7469
      operands[4] = operands[3];
7470
    }
7471
  else
7472
    {
7473
      gcc_assert (!true_regnum (operands[1]));
7474
      operands[4] = operands[1];
7475
    }
7476
})
7477
 
7478
 
7479
(define_expand "divmodsi4"
7480
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7481
                   (div:SI (match_operand:SI 1 "register_operand" "")
7482
                           (match_operand:SI 2 "nonimmediate_operand" "")))
7483
              (set (match_operand:SI 3 "register_operand" "")
7484
                   (mod:SI (match_dup 1) (match_dup 2)))
7485
              (clobber (reg:CC FLAGS_REG))])]
7486
  ""
7487
  "")
7488
 
7489
;; Allow to come the parameter in eax or edx to avoid extra moves.
7490
;; Penalize eax case slightly because it results in worse scheduling
7491
;; of code.
7492
(define_insn "*divmodsi4_nocltd"
7493
  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7494
        (div:SI (match_operand:SI 2 "register_operand" "1,0")
7495
                (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7496
   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7497
        (mod:SI (match_dup 2) (match_dup 3)))
7498
   (clobber (reg:CC FLAGS_REG))]
7499
  "!optimize_size && !TARGET_USE_CLTD"
7500
  "#"
7501
  [(set_attr "type" "multi")])
7502
 
7503
(define_insn "*divmodsi4_cltd"
7504
  [(set (match_operand:SI 0 "register_operand" "=a")
7505
        (div:SI (match_operand:SI 2 "register_operand" "a")
7506
                (match_operand:SI 3 "nonimmediate_operand" "rm")))
7507
   (set (match_operand:SI 1 "register_operand" "=&d")
7508
        (mod:SI (match_dup 2) (match_dup 3)))
7509
   (clobber (reg:CC FLAGS_REG))]
7510
  "optimize_size || TARGET_USE_CLTD"
7511
  "#"
7512
  [(set_attr "type" "multi")])
7513
 
7514
(define_insn "*divmodsi_noext"
7515
  [(set (match_operand:SI 0 "register_operand" "=a")
7516
        (div:SI (match_operand:SI 1 "register_operand" "0")
7517
                (match_operand:SI 2 "nonimmediate_operand" "rm")))
7518
   (set (match_operand:SI 3 "register_operand" "=d")
7519
        (mod:SI (match_dup 1) (match_dup 2)))
7520
   (use (match_operand:SI 4 "register_operand" "3"))
7521
   (clobber (reg:CC FLAGS_REG))]
7522
  ""
7523
  "idiv{l}\t%2"
7524
  [(set_attr "type" "idiv")
7525
   (set_attr "mode" "SI")])
7526
 
7527
(define_split
7528
  [(set (match_operand:SI 0 "register_operand" "")
7529
        (div:SI (match_operand:SI 1 "register_operand" "")
7530
                (match_operand:SI 2 "nonimmediate_operand" "")))
7531
   (set (match_operand:SI 3 "register_operand" "")
7532
        (mod:SI (match_dup 1) (match_dup 2)))
7533
   (clobber (reg:CC FLAGS_REG))]
7534
  "reload_completed"
7535
  [(parallel [(set (match_dup 3)
7536
                   (ashiftrt:SI (match_dup 4) (const_int 31)))
7537
              (clobber (reg:CC FLAGS_REG))])
7538
   (parallel [(set (match_dup 0)
7539
                   (div:SI (reg:SI 0) (match_dup 2)))
7540
              (set (match_dup 3)
7541
                   (mod:SI (reg:SI 0) (match_dup 2)))
7542
              (use (match_dup 3))
7543
              (clobber (reg:CC FLAGS_REG))])]
7544
{
7545
  /* Avoid use of cltd in favor of a mov+shift.  */
7546
  if (!TARGET_USE_CLTD && !optimize_size)
7547
    {
7548
      if (true_regnum (operands[1]))
7549
        emit_move_insn (operands[0], operands[1]);
7550
      else
7551
        emit_move_insn (operands[3], operands[1]);
7552
      operands[4] = operands[3];
7553
    }
7554
  else
7555
    {
7556
      gcc_assert (!true_regnum (operands[1]));
7557
      operands[4] = operands[1];
7558
    }
7559
})
7560
;; %%% Split me.
7561
(define_insn "divmodhi4"
7562
  [(set (match_operand:HI 0 "register_operand" "=a")
7563
        (div:HI (match_operand:HI 1 "register_operand" "0")
7564
                (match_operand:HI 2 "nonimmediate_operand" "rm")))
7565
   (set (match_operand:HI 3 "register_operand" "=&d")
7566
        (mod:HI (match_dup 1) (match_dup 2)))
7567
   (clobber (reg:CC FLAGS_REG))]
7568
  "TARGET_HIMODE_MATH"
7569
  "cwtd\;idiv{w}\t%2"
7570
  [(set_attr "type" "multi")
7571
   (set_attr "length_immediate" "0")
7572
   (set_attr "mode" "SI")])
7573
 
7574
(define_insn "udivmoddi4"
7575
  [(set (match_operand:DI 0 "register_operand" "=a")
7576
        (udiv:DI (match_operand:DI 1 "register_operand" "0")
7577
                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7578
   (set (match_operand:DI 3 "register_operand" "=&d")
7579
        (umod:DI (match_dup 1) (match_dup 2)))
7580
   (clobber (reg:CC FLAGS_REG))]
7581
  "TARGET_64BIT"
7582
  "xor{q}\t%3, %3\;div{q}\t%2"
7583
  [(set_attr "type" "multi")
7584
   (set_attr "length_immediate" "0")
7585
   (set_attr "mode" "DI")])
7586
 
7587
(define_insn "*udivmoddi4_noext"
7588
  [(set (match_operand:DI 0 "register_operand" "=a")
7589
        (udiv:DI (match_operand:DI 1 "register_operand" "0")
7590
                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7591
   (set (match_operand:DI 3 "register_operand" "=d")
7592
        (umod:DI (match_dup 1) (match_dup 2)))
7593
   (use (match_dup 3))
7594
   (clobber (reg:CC FLAGS_REG))]
7595
  "TARGET_64BIT"
7596
  "div{q}\t%2"
7597
  [(set_attr "type" "idiv")
7598
   (set_attr "mode" "DI")])
7599
 
7600
(define_split
7601
  [(set (match_operand:DI 0 "register_operand" "")
7602
        (udiv:DI (match_operand:DI 1 "register_operand" "")
7603
                 (match_operand:DI 2 "nonimmediate_operand" "")))
7604
   (set (match_operand:DI 3 "register_operand" "")
7605
        (umod:DI (match_dup 1) (match_dup 2)))
7606
   (clobber (reg:CC FLAGS_REG))]
7607
  "TARGET_64BIT && reload_completed"
7608
  [(set (match_dup 3) (const_int 0))
7609
   (parallel [(set (match_dup 0)
7610
                   (udiv:DI (match_dup 1) (match_dup 2)))
7611
              (set (match_dup 3)
7612
                   (umod:DI (match_dup 1) (match_dup 2)))
7613
              (use (match_dup 3))
7614
              (clobber (reg:CC FLAGS_REG))])]
7615
  "")
7616
 
7617
(define_insn "udivmodsi4"
7618
  [(set (match_operand:SI 0 "register_operand" "=a")
7619
        (udiv:SI (match_operand:SI 1 "register_operand" "0")
7620
                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7621
   (set (match_operand:SI 3 "register_operand" "=&d")
7622
        (umod:SI (match_dup 1) (match_dup 2)))
7623
   (clobber (reg:CC FLAGS_REG))]
7624
  ""
7625
  "xor{l}\t%3, %3\;div{l}\t%2"
7626
  [(set_attr "type" "multi")
7627
   (set_attr "length_immediate" "0")
7628
   (set_attr "mode" "SI")])
7629
 
7630
(define_insn "*udivmodsi4_noext"
7631
  [(set (match_operand:SI 0 "register_operand" "=a")
7632
        (udiv:SI (match_operand:SI 1 "register_operand" "0")
7633
                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7634
   (set (match_operand:SI 3 "register_operand" "=d")
7635
        (umod:SI (match_dup 1) (match_dup 2)))
7636
   (use (match_dup 3))
7637
   (clobber (reg:CC FLAGS_REG))]
7638
  ""
7639
  "div{l}\t%2"
7640
  [(set_attr "type" "idiv")
7641
   (set_attr "mode" "SI")])
7642
 
7643
(define_split
7644
  [(set (match_operand:SI 0 "register_operand" "")
7645
        (udiv:SI (match_operand:SI 1 "register_operand" "")
7646
                 (match_operand:SI 2 "nonimmediate_operand" "")))
7647
   (set (match_operand:SI 3 "register_operand" "")
7648
        (umod:SI (match_dup 1) (match_dup 2)))
7649
   (clobber (reg:CC FLAGS_REG))]
7650
  "reload_completed"
7651
  [(set (match_dup 3) (const_int 0))
7652
   (parallel [(set (match_dup 0)
7653
                   (udiv:SI (match_dup 1) (match_dup 2)))
7654
              (set (match_dup 3)
7655
                   (umod:SI (match_dup 1) (match_dup 2)))
7656
              (use (match_dup 3))
7657
              (clobber (reg:CC FLAGS_REG))])]
7658
  "")
7659
 
7660
(define_expand "udivmodhi4"
7661
  [(set (match_dup 4) (const_int 0))
7662
   (parallel [(set (match_operand:HI 0 "register_operand" "")
7663
                   (udiv:HI (match_operand:HI 1 "register_operand" "")
7664
                            (match_operand:HI 2 "nonimmediate_operand" "")))
7665
              (set (match_operand:HI 3 "register_operand" "")
7666
                   (umod:HI (match_dup 1) (match_dup 2)))
7667
              (use (match_dup 4))
7668
              (clobber (reg:CC FLAGS_REG))])]
7669
  "TARGET_HIMODE_MATH"
7670
  "operands[4] = gen_reg_rtx (HImode);")
7671
 
7672
(define_insn "*udivmodhi_noext"
7673
  [(set (match_operand:HI 0 "register_operand" "=a")
7674
        (udiv:HI (match_operand:HI 1 "register_operand" "0")
7675
                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7676
   (set (match_operand:HI 3 "register_operand" "=d")
7677
        (umod:HI (match_dup 1) (match_dup 2)))
7678
   (use (match_operand:HI 4 "register_operand" "3"))
7679
   (clobber (reg:CC FLAGS_REG))]
7680
  ""
7681
  "div{w}\t%2"
7682
  [(set_attr "type" "idiv")
7683
   (set_attr "mode" "HI")])
7684
 
7685
;; We cannot use div/idiv for double division, because it causes
7686
;; "division by zero" on the overflow and that's not what we expect
7687
;; from truncate.  Because true (non truncating) double division is
7688
;; never generated, we can't create this insn anyway.
7689
;
7690
;(define_insn ""
7691
;  [(set (match_operand:SI 0 "register_operand" "=a")
7692
;       (truncate:SI
7693
;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7694
;                  (zero_extend:DI
7695
;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7696
;   (set (match_operand:SI 3 "register_operand" "=d")
7697
;       (truncate:SI
7698
;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7699
;   (clobber (reg:CC FLAGS_REG))]
7700
;  ""
7701
;  "div{l}\t{%2, %0|%0, %2}"
7702
;  [(set_attr "type" "idiv")])
7703
 
7704
;;- Logical AND instructions
7705
 
7706
;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7707
;; Note that this excludes ah.
7708
 
7709
(define_insn "*testdi_1_rex64"
7710
  [(set (reg FLAGS_REG)
7711
        (compare
7712
          (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7713
                  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7714
          (const_int 0)))]
7715
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7716
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7717
  "@
7718
   test{l}\t{%k1, %k0|%k0, %k1}
7719
   test{l}\t{%k1, %k0|%k0, %k1}
7720
   test{q}\t{%1, %0|%0, %1}
7721
   test{q}\t{%1, %0|%0, %1}
7722
   test{q}\t{%1, %0|%0, %1}"
7723
  [(set_attr "type" "test")
7724
   (set_attr "modrm" "0,1,0,1,1")
7725
   (set_attr "mode" "SI,SI,DI,DI,DI")
7726
   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7727
 
7728
(define_insn "testsi_1"
7729
  [(set (reg FLAGS_REG)
7730
        (compare
7731
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7732
                  (match_operand:SI 1 "general_operand" "in,in,rin"))
7733
          (const_int 0)))]
7734
  "ix86_match_ccmode (insn, CCNOmode)
7735
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7736
  "test{l}\t{%1, %0|%0, %1}"
7737
  [(set_attr "type" "test")
7738
   (set_attr "modrm" "0,1,1")
7739
   (set_attr "mode" "SI")
7740
   (set_attr "pent_pair" "uv,np,uv")])
7741
 
7742
(define_expand "testsi_ccno_1"
7743
  [(set (reg:CCNO FLAGS_REG)
7744
        (compare:CCNO
7745
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7746
                  (match_operand:SI 1 "nonmemory_operand" ""))
7747
          (const_int 0)))]
7748
  ""
7749
  "")
7750
 
7751
(define_insn "*testhi_1"
7752
  [(set (reg FLAGS_REG)
7753
        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7754
                         (match_operand:HI 1 "general_operand" "n,n,rn"))
7755
                 (const_int 0)))]
7756
  "ix86_match_ccmode (insn, CCNOmode)
7757
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7758
  "test{w}\t{%1, %0|%0, %1}"
7759
  [(set_attr "type" "test")
7760
   (set_attr "modrm" "0,1,1")
7761
   (set_attr "mode" "HI")
7762
   (set_attr "pent_pair" "uv,np,uv")])
7763
 
7764
(define_expand "testqi_ccz_1"
7765
  [(set (reg:CCZ FLAGS_REG)
7766
        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7767
                             (match_operand:QI 1 "nonmemory_operand" ""))
7768
                 (const_int 0)))]
7769
  ""
7770
  "")
7771
 
7772
(define_insn "*testqi_1_maybe_si"
7773
  [(set (reg FLAGS_REG)
7774
        (compare
7775
          (and:QI
7776
            (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7777
            (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7778
          (const_int 0)))]
7779
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7780
    && ix86_match_ccmode (insn,
7781
                         GET_CODE (operands[1]) == CONST_INT
7782
                         && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7783
{
7784
  if (which_alternative == 3)
7785
    {
7786
      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7787
        operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7788
      return "test{l}\t{%1, %k0|%k0, %1}";
7789
    }
7790
  return "test{b}\t{%1, %0|%0, %1}";
7791
}
7792
  [(set_attr "type" "test")
7793
   (set_attr "modrm" "0,1,1,1")
7794
   (set_attr "mode" "QI,QI,QI,SI")
7795
   (set_attr "pent_pair" "uv,np,uv,np")])
7796
 
7797
(define_insn "*testqi_1"
7798
  [(set (reg FLAGS_REG)
7799
        (compare
7800
          (and:QI
7801
            (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7802
            (match_operand:QI 1 "general_operand" "n,n,qn"))
7803
          (const_int 0)))]
7804
  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7805
   && ix86_match_ccmode (insn, CCNOmode)"
7806
  "test{b}\t{%1, %0|%0, %1}"
7807
  [(set_attr "type" "test")
7808
   (set_attr "modrm" "0,1,1")
7809
   (set_attr "mode" "QI")
7810
   (set_attr "pent_pair" "uv,np,uv")])
7811
 
7812
(define_expand "testqi_ext_ccno_0"
7813
  [(set (reg:CCNO FLAGS_REG)
7814
        (compare:CCNO
7815
          (and:SI
7816
            (zero_extract:SI
7817
              (match_operand 0 "ext_register_operand" "")
7818
              (const_int 8)
7819
              (const_int 8))
7820
            (match_operand 1 "const_int_operand" ""))
7821
          (const_int 0)))]
7822
  ""
7823
  "")
7824
 
7825
(define_insn "*testqi_ext_0"
7826
  [(set (reg FLAGS_REG)
7827
        (compare
7828
          (and:SI
7829
            (zero_extract:SI
7830
              (match_operand 0 "ext_register_operand" "Q")
7831
              (const_int 8)
7832
              (const_int 8))
7833
            (match_operand 1 "const_int_operand" "n"))
7834
          (const_int 0)))]
7835
  "ix86_match_ccmode (insn, CCNOmode)"
7836
  "test{b}\t{%1, %h0|%h0, %1}"
7837
  [(set_attr "type" "test")
7838
   (set_attr "mode" "QI")
7839
   (set_attr "length_immediate" "1")
7840
   (set_attr "pent_pair" "np")])
7841
 
7842
(define_insn "*testqi_ext_1"
7843
  [(set (reg FLAGS_REG)
7844
        (compare
7845
          (and:SI
7846
            (zero_extract:SI
7847
              (match_operand 0 "ext_register_operand" "Q")
7848
              (const_int 8)
7849
              (const_int 8))
7850
            (zero_extend:SI
7851
              (match_operand:QI 1 "general_operand" "Qm")))
7852
          (const_int 0)))]
7853
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7854
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7855
  "test{b}\t{%1, %h0|%h0, %1}"
7856
  [(set_attr "type" "test")
7857
   (set_attr "mode" "QI")])
7858
 
7859
(define_insn "*testqi_ext_1_rex64"
7860
  [(set (reg FLAGS_REG)
7861
        (compare
7862
          (and:SI
7863
            (zero_extract:SI
7864
              (match_operand 0 "ext_register_operand" "Q")
7865
              (const_int 8)
7866
              (const_int 8))
7867
            (zero_extend:SI
7868
              (match_operand:QI 1 "register_operand" "Q")))
7869
          (const_int 0)))]
7870
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7871
  "test{b}\t{%1, %h0|%h0, %1}"
7872
  [(set_attr "type" "test")
7873
   (set_attr "mode" "QI")])
7874
 
7875
(define_insn "*testqi_ext_2"
7876
  [(set (reg FLAGS_REG)
7877
        (compare
7878
          (and:SI
7879
            (zero_extract:SI
7880
              (match_operand 0 "ext_register_operand" "Q")
7881
              (const_int 8)
7882
              (const_int 8))
7883
            (zero_extract:SI
7884
              (match_operand 1 "ext_register_operand" "Q")
7885
              (const_int 8)
7886
              (const_int 8)))
7887
          (const_int 0)))]
7888
  "ix86_match_ccmode (insn, CCNOmode)"
7889
  "test{b}\t{%h1, %h0|%h0, %h1}"
7890
  [(set_attr "type" "test")
7891
   (set_attr "mode" "QI")])
7892
 
7893
;; Combine likes to form bit extractions for some tests.  Humor it.
7894
(define_insn "*testqi_ext_3"
7895
  [(set (reg FLAGS_REG)
7896
        (compare (zero_extract:SI
7897
                   (match_operand 0 "nonimmediate_operand" "rm")
7898
                   (match_operand:SI 1 "const_int_operand" "")
7899
                   (match_operand:SI 2 "const_int_operand" ""))
7900
                 (const_int 0)))]
7901
  "ix86_match_ccmode (insn, CCNOmode)
7902
   && INTVAL (operands[1]) > 0
7903
   && INTVAL (operands[2]) >= 0
7904
   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7905
   && (GET_MODE (operands[0]) == SImode
7906
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7907
       || GET_MODE (operands[0]) == HImode
7908
       || GET_MODE (operands[0]) == QImode)"
7909
  "#")
7910
 
7911
(define_insn "*testqi_ext_3_rex64"
7912
  [(set (reg FLAGS_REG)
7913
        (compare (zero_extract:DI
7914
                   (match_operand 0 "nonimmediate_operand" "rm")
7915
                   (match_operand:DI 1 "const_int_operand" "")
7916
                   (match_operand:DI 2 "const_int_operand" ""))
7917
                 (const_int 0)))]
7918
  "TARGET_64BIT
7919
   && ix86_match_ccmode (insn, CCNOmode)
7920
   && INTVAL (operands[1]) > 0
7921
   && INTVAL (operands[2]) >= 0
7922
   /* Ensure that resulting mask is zero or sign extended operand.  */
7923
   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7924
       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7925
           && INTVAL (operands[1]) > 32))
7926
   && (GET_MODE (operands[0]) == SImode
7927
       || GET_MODE (operands[0]) == DImode
7928
       || GET_MODE (operands[0]) == HImode
7929
       || GET_MODE (operands[0]) == QImode)"
7930
  "#")
7931
 
7932
(define_split
7933
  [(set (match_operand 0 "flags_reg_operand" "")
7934
        (match_operator 1 "compare_operator"
7935
          [(zero_extract
7936
             (match_operand 2 "nonimmediate_operand" "")
7937
             (match_operand 3 "const_int_operand" "")
7938
             (match_operand 4 "const_int_operand" ""))
7939
           (const_int 0)]))]
7940
  "ix86_match_ccmode (insn, CCNOmode)"
7941
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7942
{
7943
  rtx val = operands[2];
7944
  HOST_WIDE_INT len = INTVAL (operands[3]);
7945
  HOST_WIDE_INT pos = INTVAL (operands[4]);
7946
  HOST_WIDE_INT mask;
7947
  enum machine_mode mode, submode;
7948
 
7949
  mode = GET_MODE (val);
7950
  if (GET_CODE (val) == MEM)
7951
    {
7952
      /* ??? Combine likes to put non-volatile mem extractions in QImode
7953
         no matter the size of the test.  So find a mode that works.  */
7954
      if (! MEM_VOLATILE_P (val))
7955
        {
7956
          mode = smallest_mode_for_size (pos + len, MODE_INT);
7957
          val = adjust_address (val, mode, 0);
7958
        }
7959
    }
7960
  else if (GET_CODE (val) == SUBREG
7961
           && (submode = GET_MODE (SUBREG_REG (val)),
7962
               GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7963
           && pos + len <= GET_MODE_BITSIZE (submode))
7964
    {
7965
      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7966
      mode = submode;
7967
      val = SUBREG_REG (val);
7968
    }
7969
  else if (mode == HImode && pos + len <= 8)
7970
    {
7971
      /* Small HImode tests can be converted to QImode.  */
7972
      mode = QImode;
7973
      val = gen_lowpart (QImode, val);
7974
    }
7975
 
7976
  if (len == HOST_BITS_PER_WIDE_INT)
7977
    mask = -1;
7978
  else
7979
    mask = ((HOST_WIDE_INT)1 << len) - 1;
7980
  mask <<= pos;
7981
 
7982
  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7983
})
7984
 
7985
;; Convert HImode/SImode test instructions with immediate to QImode ones.
7986
;; i386 does not allow to encode test with 8bit sign extended immediate, so
7987
;; this is relatively important trick.
7988
;; Do the conversion only post-reload to avoid limiting of the register class
7989
;; to QI regs.
7990
(define_split
7991
  [(set (match_operand 0 "flags_reg_operand" "")
7992
        (match_operator 1 "compare_operator"
7993
          [(and (match_operand 2 "register_operand" "")
7994
                (match_operand 3 "const_int_operand" ""))
7995
           (const_int 0)]))]
7996
   "reload_completed
7997
    && QI_REG_P (operands[2])
7998
    && GET_MODE (operands[2]) != QImode
7999
    && ((ix86_match_ccmode (insn, CCZmode)
8000
         && !(INTVAL (operands[3]) & ~(255 << 8)))
8001
        || (ix86_match_ccmode (insn, CCNOmode)
8002
            && !(INTVAL (operands[3]) & ~(127 << 8))))"
8003
  [(set (match_dup 0)
8004
        (match_op_dup 1
8005
          [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8006
                   (match_dup 3))
8007
           (const_int 0)]))]
8008
  "operands[2] = gen_lowpart (SImode, operands[2]);
8009
   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8010
 
8011
(define_split
8012
  [(set (match_operand 0 "flags_reg_operand" "")
8013
        (match_operator 1 "compare_operator"
8014
          [(and (match_operand 2 "nonimmediate_operand" "")
8015
                (match_operand 3 "const_int_operand" ""))
8016
           (const_int 0)]))]
8017
   "reload_completed
8018
    && GET_MODE (operands[2]) != QImode
8019
    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8020
    && ((ix86_match_ccmode (insn, CCZmode)
8021
         && !(INTVAL (operands[3]) & ~255))
8022
        || (ix86_match_ccmode (insn, CCNOmode)
8023
            && !(INTVAL (operands[3]) & ~127)))"
8024
  [(set (match_dup 0)
8025
        (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8026
                         (const_int 0)]))]
8027
  "operands[2] = gen_lowpart (QImode, operands[2]);
8028
   operands[3] = gen_lowpart (QImode, operands[3]);")
8029
 
8030
 
8031
;; %%% This used to optimize known byte-wide and operations to memory,
8032
;; and sometimes to QImode registers.  If this is considered useful,
8033
;; it should be done with splitters.
8034
 
8035
(define_expand "anddi3"
8036
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8037
        (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8038
                (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8039
   (clobber (reg:CC FLAGS_REG))]
8040
  "TARGET_64BIT"
8041
  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8042
 
8043
(define_insn "*anddi_1_rex64"
8044
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8045
        (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8046
                (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8047
   (clobber (reg:CC FLAGS_REG))]
8048
  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8049
{
8050
  switch (get_attr_type (insn))
8051
    {
8052
    case TYPE_IMOVX:
8053
      {
8054
        enum machine_mode mode;
8055
 
8056
        gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8057
        if (INTVAL (operands[2]) == 0xff)
8058
          mode = QImode;
8059
        else
8060
          {
8061
            gcc_assert (INTVAL (operands[2]) == 0xffff);
8062
            mode = HImode;
8063
          }
8064
 
8065
        operands[1] = gen_lowpart (mode, operands[1]);
8066
        if (mode == QImode)
8067
          return "movz{bq|x}\t{%1,%0|%0, %1}";
8068
        else
8069
          return "movz{wq|x}\t{%1,%0|%0, %1}";
8070
      }
8071
 
8072
    default:
8073
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8074
      if (get_attr_mode (insn) == MODE_SI)
8075
        return "and{l}\t{%k2, %k0|%k0, %k2}";
8076
      else
8077
        return "and{q}\t{%2, %0|%0, %2}";
8078
    }
8079
}
8080
  [(set_attr "type" "alu,alu,alu,imovx")
8081
   (set_attr "length_immediate" "*,*,*,0")
8082
   (set_attr "mode" "SI,DI,DI,DI")])
8083
 
8084
(define_insn "*anddi_2"
8085
  [(set (reg FLAGS_REG)
8086
        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8087
                         (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8088
                 (const_int 0)))
8089
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8090
        (and:DI (match_dup 1) (match_dup 2)))]
8091
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092
   && ix86_binary_operator_ok (AND, DImode, operands)"
8093
  "@
8094
   and{l}\t{%k2, %k0|%k0, %k2}
8095
   and{q}\t{%2, %0|%0, %2}
8096
   and{q}\t{%2, %0|%0, %2}"
8097
  [(set_attr "type" "alu")
8098
   (set_attr "mode" "SI,DI,DI")])
8099
 
8100
(define_expand "andsi3"
8101
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8102
        (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8103
                (match_operand:SI 2 "general_operand" "")))
8104
   (clobber (reg:CC FLAGS_REG))]
8105
  ""
8106
  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8107
 
8108
(define_insn "*andsi_1"
8109
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8110
        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8111
                (match_operand:SI 2 "general_operand" "ri,rm,L")))
8112
   (clobber (reg:CC FLAGS_REG))]
8113
  "ix86_binary_operator_ok (AND, SImode, operands)"
8114
{
8115
  switch (get_attr_type (insn))
8116
    {
8117
    case TYPE_IMOVX:
8118
      {
8119
        enum machine_mode mode;
8120
 
8121
        gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8122
        if (INTVAL (operands[2]) == 0xff)
8123
          mode = QImode;
8124
        else
8125
          {
8126
            gcc_assert (INTVAL (operands[2]) == 0xffff);
8127
            mode = HImode;
8128
          }
8129
 
8130
        operands[1] = gen_lowpart (mode, operands[1]);
8131
        if (mode == QImode)
8132
          return "movz{bl|x}\t{%1,%0|%0, %1}";
8133
        else
8134
          return "movz{wl|x}\t{%1,%0|%0, %1}";
8135
      }
8136
 
8137
    default:
8138
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8139
      return "and{l}\t{%2, %0|%0, %2}";
8140
    }
8141
}
8142
  [(set_attr "type" "alu,alu,imovx")
8143
   (set_attr "length_immediate" "*,*,0")
8144
   (set_attr "mode" "SI")])
8145
 
8146
(define_split
8147
  [(set (match_operand 0 "register_operand" "")
8148
        (and (match_dup 0)
8149
             (const_int -65536)))
8150
   (clobber (reg:CC FLAGS_REG))]
8151
  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8152
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8153
  "operands[1] = gen_lowpart (HImode, operands[0]);")
8154
 
8155
(define_split
8156
  [(set (match_operand 0 "ext_register_operand" "")
8157
        (and (match_dup 0)
8158
             (const_int -256)))
8159
   (clobber (reg:CC FLAGS_REG))]
8160
  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8161
  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8162
  "operands[1] = gen_lowpart (QImode, operands[0]);")
8163
 
8164
(define_split
8165
  [(set (match_operand 0 "ext_register_operand" "")
8166
        (and (match_dup 0)
8167
             (const_int -65281)))
8168
   (clobber (reg:CC FLAGS_REG))]
8169
  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8170
  [(parallel [(set (zero_extract:SI (match_dup 0)
8171
                                    (const_int 8)
8172
                                    (const_int 8))
8173
                   (xor:SI
8174
                     (zero_extract:SI (match_dup 0)
8175
                                      (const_int 8)
8176
                                      (const_int 8))
8177
                     (zero_extract:SI (match_dup 0)
8178
                                      (const_int 8)
8179
                                      (const_int 8))))
8180
              (clobber (reg:CC FLAGS_REG))])]
8181
  "operands[0] = gen_lowpart (SImode, operands[0]);")
8182
 
8183
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8184
(define_insn "*andsi_1_zext"
8185
  [(set (match_operand:DI 0 "register_operand" "=r")
8186
        (zero_extend:DI
8187
          (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8188
                  (match_operand:SI 2 "general_operand" "rim"))))
8189
   (clobber (reg:CC FLAGS_REG))]
8190
  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8191
  "and{l}\t{%2, %k0|%k0, %2}"
8192
  [(set_attr "type" "alu")
8193
   (set_attr "mode" "SI")])
8194
 
8195
(define_insn "*andsi_2"
8196
  [(set (reg FLAGS_REG)
8197
        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8198
                         (match_operand:SI 2 "general_operand" "rim,ri"))
8199
                 (const_int 0)))
8200
   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8201
        (and:SI (match_dup 1) (match_dup 2)))]
8202
  "ix86_match_ccmode (insn, CCNOmode)
8203
   && ix86_binary_operator_ok (AND, SImode, operands)"
8204
  "and{l}\t{%2, %0|%0, %2}"
8205
  [(set_attr "type" "alu")
8206
   (set_attr "mode" "SI")])
8207
 
8208
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8209
(define_insn "*andsi_2_zext"
8210
  [(set (reg FLAGS_REG)
8211
        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8212
                         (match_operand:SI 2 "general_operand" "rim"))
8213
                 (const_int 0)))
8214
   (set (match_operand:DI 0 "register_operand" "=r")
8215
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8216
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8217
   && ix86_binary_operator_ok (AND, SImode, operands)"
8218
  "and{l}\t{%2, %k0|%k0, %2}"
8219
  [(set_attr "type" "alu")
8220
   (set_attr "mode" "SI")])
8221
 
8222
(define_expand "andhi3"
8223
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8224
        (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8225
                (match_operand:HI 2 "general_operand" "")))
8226
   (clobber (reg:CC FLAGS_REG))]
8227
  "TARGET_HIMODE_MATH"
8228
  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8229
 
8230
(define_insn "*andhi_1"
8231
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8232
        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8233
                (match_operand:HI 2 "general_operand" "ri,rm,L")))
8234
   (clobber (reg:CC FLAGS_REG))]
8235
  "ix86_binary_operator_ok (AND, HImode, operands)"
8236
{
8237
  switch (get_attr_type (insn))
8238
    {
8239
    case TYPE_IMOVX:
8240
      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8241
      gcc_assert (INTVAL (operands[2]) == 0xff);
8242
      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8243
 
8244
    default:
8245
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8246
 
8247
      return "and{w}\t{%2, %0|%0, %2}";
8248
    }
8249
}
8250
  [(set_attr "type" "alu,alu,imovx")
8251
   (set_attr "length_immediate" "*,*,0")
8252
   (set_attr "mode" "HI,HI,SI")])
8253
 
8254
(define_insn "*andhi_2"
8255
  [(set (reg FLAGS_REG)
8256
        (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8257
                         (match_operand:HI 2 "general_operand" "rim,ri"))
8258
                 (const_int 0)))
8259
   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8260
        (and:HI (match_dup 1) (match_dup 2)))]
8261
  "ix86_match_ccmode (insn, CCNOmode)
8262
   && ix86_binary_operator_ok (AND, HImode, operands)"
8263
  "and{w}\t{%2, %0|%0, %2}"
8264
  [(set_attr "type" "alu")
8265
   (set_attr "mode" "HI")])
8266
 
8267
(define_expand "andqi3"
8268
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8269
        (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8270
                (match_operand:QI 2 "general_operand" "")))
8271
   (clobber (reg:CC FLAGS_REG))]
8272
  "TARGET_QIMODE_MATH"
8273
  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8274
 
8275
;; %%% Potential partial reg stall on alternative 2.  What to do?
8276
(define_insn "*andqi_1"
8277
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8278
        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8279
                (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8280
   (clobber (reg:CC FLAGS_REG))]
8281
  "ix86_binary_operator_ok (AND, QImode, operands)"
8282
  "@
8283
   and{b}\t{%2, %0|%0, %2}
8284
   and{b}\t{%2, %0|%0, %2}
8285
   and{l}\t{%k2, %k0|%k0, %k2}"
8286
  [(set_attr "type" "alu")
8287
   (set_attr "mode" "QI,QI,SI")])
8288
 
8289
(define_insn "*andqi_1_slp"
8290
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8291
        (and:QI (match_dup 0)
8292
                (match_operand:QI 1 "general_operand" "qi,qmi")))
8293
   (clobber (reg:CC FLAGS_REG))]
8294
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8295
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8296
  "and{b}\t{%1, %0|%0, %1}"
8297
  [(set_attr "type" "alu1")
8298
   (set_attr "mode" "QI")])
8299
 
8300
(define_insn "*andqi_2_maybe_si"
8301
  [(set (reg FLAGS_REG)
8302
        (compare (and:QI
8303
                      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8304
                      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8305
                 (const_int 0)))
8306
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8307
        (and:QI (match_dup 1) (match_dup 2)))]
8308
  "ix86_binary_operator_ok (AND, QImode, operands)
8309
   && ix86_match_ccmode (insn,
8310
                         GET_CODE (operands[2]) == CONST_INT
8311
                         && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8312
{
8313
  if (which_alternative == 2)
8314
    {
8315
      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8316
        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8317
      return "and{l}\t{%2, %k0|%k0, %2}";
8318
    }
8319
  return "and{b}\t{%2, %0|%0, %2}";
8320
}
8321
  [(set_attr "type" "alu")
8322
   (set_attr "mode" "QI,QI,SI")])
8323
 
8324
(define_insn "*andqi_2"
8325
  [(set (reg FLAGS_REG)
8326
        (compare (and:QI
8327
                   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8328
                   (match_operand:QI 2 "general_operand" "qim,qi"))
8329
                 (const_int 0)))
8330
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8331
        (and:QI (match_dup 1) (match_dup 2)))]
8332
  "ix86_match_ccmode (insn, CCNOmode)
8333
   && ix86_binary_operator_ok (AND, QImode, operands)"
8334
  "and{b}\t{%2, %0|%0, %2}"
8335
  [(set_attr "type" "alu")
8336
   (set_attr "mode" "QI")])
8337
 
8338
(define_insn "*andqi_2_slp"
8339
  [(set (reg FLAGS_REG)
8340
        (compare (and:QI
8341
                   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8342
                   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8343
                 (const_int 0)))
8344
   (set (strict_low_part (match_dup 0))
8345
        (and:QI (match_dup 0) (match_dup 1)))]
8346
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8347
   && ix86_match_ccmode (insn, CCNOmode)
8348
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8349
  "and{b}\t{%1, %0|%0, %1}"
8350
  [(set_attr "type" "alu1")
8351
   (set_attr "mode" "QI")])
8352
 
8353
;; ??? A bug in recog prevents it from recognizing a const_int as an
8354
;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8355
;; for a QImode operand, which of course failed.
8356
 
8357
(define_insn "andqi_ext_0"
8358
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359
                         (const_int 8)
8360
                         (const_int 8))
8361
        (and:SI
8362
          (zero_extract:SI
8363
            (match_operand 1 "ext_register_operand" "0")
8364
            (const_int 8)
8365
            (const_int 8))
8366
          (match_operand 2 "const_int_operand" "n")))
8367
   (clobber (reg:CC FLAGS_REG))]
8368
  ""
8369
  "and{b}\t{%2, %h0|%h0, %2}"
8370
  [(set_attr "type" "alu")
8371
   (set_attr "length_immediate" "1")
8372
   (set_attr "mode" "QI")])
8373
 
8374
;; Generated by peephole translating test to and.  This shows up
8375
;; often in fp comparisons.
8376
 
8377
(define_insn "*andqi_ext_0_cc"
8378
  [(set (reg FLAGS_REG)
8379
        (compare
8380
          (and:SI
8381
            (zero_extract:SI
8382
              (match_operand 1 "ext_register_operand" "0")
8383
              (const_int 8)
8384
              (const_int 8))
8385
            (match_operand 2 "const_int_operand" "n"))
8386
          (const_int 0)))
8387
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388
                         (const_int 8)
8389
                         (const_int 8))
8390
        (and:SI
8391
          (zero_extract:SI
8392
            (match_dup 1)
8393
            (const_int 8)
8394
            (const_int 8))
8395
          (match_dup 2)))]
8396
  "ix86_match_ccmode (insn, CCNOmode)"
8397
  "and{b}\t{%2, %h0|%h0, %2}"
8398
  [(set_attr "type" "alu")
8399
   (set_attr "length_immediate" "1")
8400
   (set_attr "mode" "QI")])
8401
 
8402
(define_insn "*andqi_ext_1"
8403
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404
                         (const_int 8)
8405
                         (const_int 8))
8406
        (and:SI
8407
          (zero_extract:SI
8408
            (match_operand 1 "ext_register_operand" "0")
8409
            (const_int 8)
8410
            (const_int 8))
8411
          (zero_extend:SI
8412
            (match_operand:QI 2 "general_operand" "Qm"))))
8413
   (clobber (reg:CC FLAGS_REG))]
8414
  "!TARGET_64BIT"
8415
  "and{b}\t{%2, %h0|%h0, %2}"
8416
  [(set_attr "type" "alu")
8417
   (set_attr "length_immediate" "0")
8418
   (set_attr "mode" "QI")])
8419
 
8420
(define_insn "*andqi_ext_1_rex64"
8421
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422
                         (const_int 8)
8423
                         (const_int 8))
8424
        (and:SI
8425
          (zero_extract:SI
8426
            (match_operand 1 "ext_register_operand" "0")
8427
            (const_int 8)
8428
            (const_int 8))
8429
          (zero_extend:SI
8430
            (match_operand 2 "ext_register_operand" "Q"))))
8431
   (clobber (reg:CC FLAGS_REG))]
8432
  "TARGET_64BIT"
8433
  "and{b}\t{%2, %h0|%h0, %2}"
8434
  [(set_attr "type" "alu")
8435
   (set_attr "length_immediate" "0")
8436
   (set_attr "mode" "QI")])
8437
 
8438
(define_insn "*andqi_ext_2"
8439
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8440
                         (const_int 8)
8441
                         (const_int 8))
8442
        (and:SI
8443
          (zero_extract:SI
8444
            (match_operand 1 "ext_register_operand" "%0")
8445
            (const_int 8)
8446
            (const_int 8))
8447
          (zero_extract:SI
8448
            (match_operand 2 "ext_register_operand" "Q")
8449
            (const_int 8)
8450
            (const_int 8))))
8451
   (clobber (reg:CC FLAGS_REG))]
8452
  ""
8453
  "and{b}\t{%h2, %h0|%h0, %h2}"
8454
  [(set_attr "type" "alu")
8455
   (set_attr "length_immediate" "0")
8456
   (set_attr "mode" "QI")])
8457
 
8458
;; Convert wide AND instructions with immediate operand to shorter QImode
8459
;; equivalents when possible.
8460
;; Don't do the splitting with memory operands, since it introduces risk
8461
;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8462
;; for size, but that can (should?) be handled by generic code instead.
8463
(define_split
8464
  [(set (match_operand 0 "register_operand" "")
8465
        (and (match_operand 1 "register_operand" "")
8466
             (match_operand 2 "const_int_operand" "")))
8467
   (clobber (reg:CC FLAGS_REG))]
8468
   "reload_completed
8469
    && QI_REG_P (operands[0])
8470
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8471
    && !(~INTVAL (operands[2]) & ~(255 << 8))
8472
    && GET_MODE (operands[0]) != QImode"
8473
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8474
                   (and:SI (zero_extract:SI (match_dup 1)
8475
                                            (const_int 8) (const_int 8))
8476
                           (match_dup 2)))
8477
              (clobber (reg:CC FLAGS_REG))])]
8478
  "operands[0] = gen_lowpart (SImode, operands[0]);
8479
   operands[1] = gen_lowpart (SImode, operands[1]);
8480
   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8481
 
8482
;; Since AND can be encoded with sign extended immediate, this is only
8483
;; profitable when 7th bit is not set.
8484
(define_split
8485
  [(set (match_operand 0 "register_operand" "")
8486
        (and (match_operand 1 "general_operand" "")
8487
             (match_operand 2 "const_int_operand" "")))
8488
   (clobber (reg:CC FLAGS_REG))]
8489
   "reload_completed
8490
    && ANY_QI_REG_P (operands[0])
8491
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8492
    && !(~INTVAL (operands[2]) & ~255)
8493
    && !(INTVAL (operands[2]) & 128)
8494
    && GET_MODE (operands[0]) != QImode"
8495
  [(parallel [(set (strict_low_part (match_dup 0))
8496
                   (and:QI (match_dup 1)
8497
                           (match_dup 2)))
8498
              (clobber (reg:CC FLAGS_REG))])]
8499
  "operands[0] = gen_lowpart (QImode, operands[0]);
8500
   operands[1] = gen_lowpart (QImode, operands[1]);
8501
   operands[2] = gen_lowpart (QImode, operands[2]);")
8502
 
8503
;; Logical inclusive OR instructions
8504
 
8505
;; %%% This used to optimize known byte-wide and operations to memory.
8506
;; If this is considered useful, it should be done with splitters.
8507
 
8508
(define_expand "iordi3"
8509
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8510
        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8511
                (match_operand:DI 2 "x86_64_general_operand" "")))
8512
   (clobber (reg:CC FLAGS_REG))]
8513
  "TARGET_64BIT"
8514
  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8515
 
8516
(define_insn "*iordi_1_rex64"
8517
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8518
        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8519
                (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8520
   (clobber (reg:CC FLAGS_REG))]
8521
  "TARGET_64BIT
8522
   && ix86_binary_operator_ok (IOR, DImode, operands)"
8523
  "or{q}\t{%2, %0|%0, %2}"
8524
  [(set_attr "type" "alu")
8525
   (set_attr "mode" "DI")])
8526
 
8527
(define_insn "*iordi_2_rex64"
8528
  [(set (reg FLAGS_REG)
8529
        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8530
                         (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8531
                 (const_int 0)))
8532
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8533
        (ior:DI (match_dup 1) (match_dup 2)))]
8534
  "TARGET_64BIT
8535
   && ix86_match_ccmode (insn, CCNOmode)
8536
   && ix86_binary_operator_ok (IOR, DImode, operands)"
8537
  "or{q}\t{%2, %0|%0, %2}"
8538
  [(set_attr "type" "alu")
8539
   (set_attr "mode" "DI")])
8540
 
8541
(define_insn "*iordi_3_rex64"
8542
  [(set (reg FLAGS_REG)
8543
        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8544
                         (match_operand:DI 2 "x86_64_general_operand" "rem"))
8545
                 (const_int 0)))
8546
   (clobber (match_scratch:DI 0 "=r"))]
8547
  "TARGET_64BIT
8548
   && ix86_match_ccmode (insn, CCNOmode)
8549
   && ix86_binary_operator_ok (IOR, DImode, operands)"
8550
  "or{q}\t{%2, %0|%0, %2}"
8551
  [(set_attr "type" "alu")
8552
   (set_attr "mode" "DI")])
8553
 
8554
 
8555
(define_expand "iorsi3"
8556
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8557
        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8558
                (match_operand:SI 2 "general_operand" "")))
8559
   (clobber (reg:CC FLAGS_REG))]
8560
  ""
8561
  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8562
 
8563
(define_insn "*iorsi_1"
8564
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8565
        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8566
                (match_operand:SI 2 "general_operand" "ri,rmi")))
8567
   (clobber (reg:CC FLAGS_REG))]
8568
  "ix86_binary_operator_ok (IOR, SImode, operands)"
8569
  "or{l}\t{%2, %0|%0, %2}"
8570
  [(set_attr "type" "alu")
8571
   (set_attr "mode" "SI")])
8572
 
8573
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8574
(define_insn "*iorsi_1_zext"
8575
  [(set (match_operand:DI 0 "register_operand" "=rm")
8576
        (zero_extend:DI
8577
          (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8578
                  (match_operand:SI 2 "general_operand" "rim"))))
8579
   (clobber (reg:CC FLAGS_REG))]
8580
  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8581
  "or{l}\t{%2, %k0|%k0, %2}"
8582
  [(set_attr "type" "alu")
8583
   (set_attr "mode" "SI")])
8584
 
8585
(define_insn "*iorsi_1_zext_imm"
8586
  [(set (match_operand:DI 0 "register_operand" "=rm")
8587
        (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8588
                (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8589
   (clobber (reg:CC FLAGS_REG))]
8590
  "TARGET_64BIT"
8591
  "or{l}\t{%2, %k0|%k0, %2}"
8592
  [(set_attr "type" "alu")
8593
   (set_attr "mode" "SI")])
8594
 
8595
(define_insn "*iorsi_2"
8596
  [(set (reg FLAGS_REG)
8597
        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8598
                         (match_operand:SI 2 "general_operand" "rim,ri"))
8599
                 (const_int 0)))
8600
   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8601
        (ior:SI (match_dup 1) (match_dup 2)))]
8602
  "ix86_match_ccmode (insn, CCNOmode)
8603
   && ix86_binary_operator_ok (IOR, SImode, operands)"
8604
  "or{l}\t{%2, %0|%0, %2}"
8605
  [(set_attr "type" "alu")
8606
   (set_attr "mode" "SI")])
8607
 
8608
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8609
;; ??? Special case for immediate operand is missing - it is tricky.
8610
(define_insn "*iorsi_2_zext"
8611
  [(set (reg FLAGS_REG)
8612
        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8613
                         (match_operand:SI 2 "general_operand" "rim"))
8614
                 (const_int 0)))
8615
   (set (match_operand:DI 0 "register_operand" "=r")
8616
        (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8617
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8618
   && ix86_binary_operator_ok (IOR, SImode, operands)"
8619
  "or{l}\t{%2, %k0|%k0, %2}"
8620
  [(set_attr "type" "alu")
8621
   (set_attr "mode" "SI")])
8622
 
8623
(define_insn "*iorsi_2_zext_imm"
8624
  [(set (reg FLAGS_REG)
8625
        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626
                         (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8627
                 (const_int 0)))
8628
   (set (match_operand:DI 0 "register_operand" "=r")
8629
        (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8630
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8631
   && ix86_binary_operator_ok (IOR, SImode, operands)"
8632
  "or{l}\t{%2, %k0|%k0, %2}"
8633
  [(set_attr "type" "alu")
8634
   (set_attr "mode" "SI")])
8635
 
8636
(define_insn "*iorsi_3"
8637
  [(set (reg FLAGS_REG)
8638
        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8639
                         (match_operand:SI 2 "general_operand" "rim"))
8640
                 (const_int 0)))
8641
   (clobber (match_scratch:SI 0 "=r"))]
8642
  "ix86_match_ccmode (insn, CCNOmode)
8643
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8644
  "or{l}\t{%2, %0|%0, %2}"
8645
  [(set_attr "type" "alu")
8646
   (set_attr "mode" "SI")])
8647
 
8648
(define_expand "iorhi3"
8649
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8650
        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8651
                (match_operand:HI 2 "general_operand" "")))
8652
   (clobber (reg:CC FLAGS_REG))]
8653
  "TARGET_HIMODE_MATH"
8654
  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8655
 
8656
(define_insn "*iorhi_1"
8657
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8658
        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8659
                (match_operand:HI 2 "general_operand" "rmi,ri")))
8660
   (clobber (reg:CC FLAGS_REG))]
8661
  "ix86_binary_operator_ok (IOR, HImode, operands)"
8662
  "or{w}\t{%2, %0|%0, %2}"
8663
  [(set_attr "type" "alu")
8664
   (set_attr "mode" "HI")])
8665
 
8666
(define_insn "*iorhi_2"
8667
  [(set (reg FLAGS_REG)
8668
        (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8669
                         (match_operand:HI 2 "general_operand" "rim,ri"))
8670
                 (const_int 0)))
8671
   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8672
        (ior:HI (match_dup 1) (match_dup 2)))]
8673
  "ix86_match_ccmode (insn, CCNOmode)
8674
   && ix86_binary_operator_ok (IOR, HImode, operands)"
8675
  "or{w}\t{%2, %0|%0, %2}"
8676
  [(set_attr "type" "alu")
8677
   (set_attr "mode" "HI")])
8678
 
8679
(define_insn "*iorhi_3"
8680
  [(set (reg FLAGS_REG)
8681
        (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8682
                         (match_operand:HI 2 "general_operand" "rim"))
8683
                 (const_int 0)))
8684
   (clobber (match_scratch:HI 0 "=r"))]
8685
  "ix86_match_ccmode (insn, CCNOmode)
8686
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8687
  "or{w}\t{%2, %0|%0, %2}"
8688
  [(set_attr "type" "alu")
8689
   (set_attr "mode" "HI")])
8690
 
8691
(define_expand "iorqi3"
8692
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8693
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8694
                (match_operand:QI 2 "general_operand" "")))
8695
   (clobber (reg:CC FLAGS_REG))]
8696
  "TARGET_QIMODE_MATH"
8697
  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8698
 
8699
;; %%% Potential partial reg stall on alternative 2.  What to do?
8700
(define_insn "*iorqi_1"
8701
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8702
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8703
                (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8704
   (clobber (reg:CC FLAGS_REG))]
8705
  "ix86_binary_operator_ok (IOR, QImode, operands)"
8706
  "@
8707
   or{b}\t{%2, %0|%0, %2}
8708
   or{b}\t{%2, %0|%0, %2}
8709
   or{l}\t{%k2, %k0|%k0, %k2}"
8710
  [(set_attr "type" "alu")
8711
   (set_attr "mode" "QI,QI,SI")])
8712
 
8713
(define_insn "*iorqi_1_slp"
8714
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8715
        (ior:QI (match_dup 0)
8716
                (match_operand:QI 1 "general_operand" "qmi,qi")))
8717
   (clobber (reg:CC FLAGS_REG))]
8718
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8719
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8720
  "or{b}\t{%1, %0|%0, %1}"
8721
  [(set_attr "type" "alu1")
8722
   (set_attr "mode" "QI")])
8723
 
8724
(define_insn "*iorqi_2"
8725
  [(set (reg FLAGS_REG)
8726
        (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8727
                         (match_operand:QI 2 "general_operand" "qim,qi"))
8728
                 (const_int 0)))
8729
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8730
        (ior:QI (match_dup 1) (match_dup 2)))]
8731
  "ix86_match_ccmode (insn, CCNOmode)
8732
   && ix86_binary_operator_ok (IOR, QImode, operands)"
8733
  "or{b}\t{%2, %0|%0, %2}"
8734
  [(set_attr "type" "alu")
8735
   (set_attr "mode" "QI")])
8736
 
8737
(define_insn "*iorqi_2_slp"
8738
  [(set (reg FLAGS_REG)
8739
        (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8740
                         (match_operand:QI 1 "general_operand" "qim,qi"))
8741
                 (const_int 0)))
8742
   (set (strict_low_part (match_dup 0))
8743
        (ior:QI (match_dup 0) (match_dup 1)))]
8744
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8745
   && ix86_match_ccmode (insn, CCNOmode)
8746
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8747
  "or{b}\t{%1, %0|%0, %1}"
8748
  [(set_attr "type" "alu1")
8749
   (set_attr "mode" "QI")])
8750
 
8751
(define_insn "*iorqi_3"
8752
  [(set (reg FLAGS_REG)
8753
        (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8754
                         (match_operand:QI 2 "general_operand" "qim"))
8755
                 (const_int 0)))
8756
   (clobber (match_scratch:QI 0 "=q"))]
8757
  "ix86_match_ccmode (insn, CCNOmode)
8758
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8759
  "or{b}\t{%2, %0|%0, %2}"
8760
  [(set_attr "type" "alu")
8761
   (set_attr "mode" "QI")])
8762
 
8763
(define_insn "iorqi_ext_0"
8764
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765
                         (const_int 8)
8766
                         (const_int 8))
8767
        (ior:SI
8768
          (zero_extract:SI
8769
            (match_operand 1 "ext_register_operand" "0")
8770
            (const_int 8)
8771
            (const_int 8))
8772
          (match_operand 2 "const_int_operand" "n")))
8773
   (clobber (reg:CC FLAGS_REG))]
8774
  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775
  "or{b}\t{%2, %h0|%h0, %2}"
8776
  [(set_attr "type" "alu")
8777
   (set_attr "length_immediate" "1")
8778
   (set_attr "mode" "QI")])
8779
 
8780
(define_insn "*iorqi_ext_1"
8781
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782
                         (const_int 8)
8783
                         (const_int 8))
8784
        (ior:SI
8785
          (zero_extract:SI
8786
            (match_operand 1 "ext_register_operand" "0")
8787
            (const_int 8)
8788
            (const_int 8))
8789
          (zero_extend:SI
8790
            (match_operand:QI 2 "general_operand" "Qm"))))
8791
   (clobber (reg:CC FLAGS_REG))]
8792
  "!TARGET_64BIT
8793
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8794
  "or{b}\t{%2, %h0|%h0, %2}"
8795
  [(set_attr "type" "alu")
8796
   (set_attr "length_immediate" "0")
8797
   (set_attr "mode" "QI")])
8798
 
8799
(define_insn "*iorqi_ext_1_rex64"
8800
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801
                         (const_int 8)
8802
                         (const_int 8))
8803
        (ior:SI
8804
          (zero_extract:SI
8805
            (match_operand 1 "ext_register_operand" "0")
8806
            (const_int 8)
8807
            (const_int 8))
8808
          (zero_extend:SI
8809
            (match_operand 2 "ext_register_operand" "Q"))))
8810
   (clobber (reg:CC FLAGS_REG))]
8811
  "TARGET_64BIT
8812
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813
  "or{b}\t{%2, %h0|%h0, %2}"
8814
  [(set_attr "type" "alu")
8815
   (set_attr "length_immediate" "0")
8816
   (set_attr "mode" "QI")])
8817
 
8818
(define_insn "*iorqi_ext_2"
8819
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820
                         (const_int 8)
8821
                         (const_int 8))
8822
        (ior:SI
8823
          (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8824
                           (const_int 8)
8825
                           (const_int 8))
8826
          (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8827
                           (const_int 8)
8828
                           (const_int 8))))
8829
   (clobber (reg:CC FLAGS_REG))]
8830
  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831
  "ior{b}\t{%h2, %h0|%h0, %h2}"
8832
  [(set_attr "type" "alu")
8833
   (set_attr "length_immediate" "0")
8834
   (set_attr "mode" "QI")])
8835
 
8836
(define_split
8837
  [(set (match_operand 0 "register_operand" "")
8838
        (ior (match_operand 1 "register_operand" "")
8839
             (match_operand 2 "const_int_operand" "")))
8840
   (clobber (reg:CC FLAGS_REG))]
8841
   "reload_completed
8842
    && QI_REG_P (operands[0])
8843
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844
    && !(INTVAL (operands[2]) & ~(255 << 8))
8845
    && GET_MODE (operands[0]) != QImode"
8846
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847
                   (ior:SI (zero_extract:SI (match_dup 1)
8848
                                            (const_int 8) (const_int 8))
8849
                           (match_dup 2)))
8850
              (clobber (reg:CC FLAGS_REG))])]
8851
  "operands[0] = gen_lowpart (SImode, operands[0]);
8852
   operands[1] = gen_lowpart (SImode, operands[1]);
8853
   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854
 
8855
;; Since OR can be encoded with sign extended immediate, this is only
8856
;; profitable when 7th bit is set.
8857
(define_split
8858
  [(set (match_operand 0 "register_operand" "")
8859
        (ior (match_operand 1 "general_operand" "")
8860
             (match_operand 2 "const_int_operand" "")))
8861
   (clobber (reg:CC FLAGS_REG))]
8862
   "reload_completed
8863
    && ANY_QI_REG_P (operands[0])
8864
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865
    && !(INTVAL (operands[2]) & ~255)
8866
    && (INTVAL (operands[2]) & 128)
8867
    && GET_MODE (operands[0]) != QImode"
8868
  [(parallel [(set (strict_low_part (match_dup 0))
8869
                   (ior:QI (match_dup 1)
8870
                           (match_dup 2)))
8871
              (clobber (reg:CC FLAGS_REG))])]
8872
  "operands[0] = gen_lowpart (QImode, operands[0]);
8873
   operands[1] = gen_lowpart (QImode, operands[1]);
8874
   operands[2] = gen_lowpart (QImode, operands[2]);")
8875
 
8876
;; Logical XOR instructions
8877
 
8878
;; %%% This used to optimize known byte-wide and operations to memory.
8879
;; If this is considered useful, it should be done with splitters.
8880
 
8881
(define_expand "xordi3"
8882
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883
        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884
                (match_operand:DI 2 "x86_64_general_operand" "")))
8885
   (clobber (reg:CC FLAGS_REG))]
8886
  "TARGET_64BIT"
8887
  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8888
 
8889
(define_insn "*xordi_1_rex64"
8890
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891
        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892
                (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8893
   (clobber (reg:CC FLAGS_REG))]
8894
  "TARGET_64BIT
8895
   && ix86_binary_operator_ok (XOR, DImode, operands)"
8896
  "@
8897
   xor{q}\t{%2, %0|%0, %2}
8898
   xor{q}\t{%2, %0|%0, %2}"
8899
  [(set_attr "type" "alu")
8900
   (set_attr "mode" "DI,DI")])
8901
 
8902
(define_insn "*xordi_2_rex64"
8903
  [(set (reg FLAGS_REG)
8904
        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8905
                         (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8906
                 (const_int 0)))
8907
   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8908
        (xor:DI (match_dup 1) (match_dup 2)))]
8909
  "TARGET_64BIT
8910
   && ix86_match_ccmode (insn, CCNOmode)
8911
   && ix86_binary_operator_ok (XOR, DImode, operands)"
8912
  "@
8913
   xor{q}\t{%2, %0|%0, %2}
8914
   xor{q}\t{%2, %0|%0, %2}"
8915
  [(set_attr "type" "alu")
8916
   (set_attr "mode" "DI,DI")])
8917
 
8918
(define_insn "*xordi_3_rex64"
8919
  [(set (reg FLAGS_REG)
8920
        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8921
                         (match_operand:DI 2 "x86_64_general_operand" "rem"))
8922
                 (const_int 0)))
8923
   (clobber (match_scratch:DI 0 "=r"))]
8924
  "TARGET_64BIT
8925
   && ix86_match_ccmode (insn, CCNOmode)
8926
   && ix86_binary_operator_ok (XOR, DImode, operands)"
8927
  "xor{q}\t{%2, %0|%0, %2}"
8928
  [(set_attr "type" "alu")
8929
   (set_attr "mode" "DI")])
8930
 
8931
(define_expand "xorsi3"
8932
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8933
        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8934
                (match_operand:SI 2 "general_operand" "")))
8935
   (clobber (reg:CC FLAGS_REG))]
8936
  ""
8937
  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8938
 
8939
(define_insn "*xorsi_1"
8940
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8941
        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942
                (match_operand:SI 2 "general_operand" "ri,rm")))
8943
   (clobber (reg:CC FLAGS_REG))]
8944
  "ix86_binary_operator_ok (XOR, SImode, operands)"
8945
  "xor{l}\t{%2, %0|%0, %2}"
8946
  [(set_attr "type" "alu")
8947
   (set_attr "mode" "SI")])
8948
 
8949
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950
;; Add speccase for immediates
8951
(define_insn "*xorsi_1_zext"
8952
  [(set (match_operand:DI 0 "register_operand" "=r")
8953
        (zero_extend:DI
8954
          (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955
                  (match_operand:SI 2 "general_operand" "rim"))))
8956
   (clobber (reg:CC FLAGS_REG))]
8957
  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8958
  "xor{l}\t{%2, %k0|%k0, %2}"
8959
  [(set_attr "type" "alu")
8960
   (set_attr "mode" "SI")])
8961
 
8962
(define_insn "*xorsi_1_zext_imm"
8963
  [(set (match_operand:DI 0 "register_operand" "=r")
8964
        (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8965
                (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8966
   (clobber (reg:CC FLAGS_REG))]
8967
  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8968
  "xor{l}\t{%2, %k0|%k0, %2}"
8969
  [(set_attr "type" "alu")
8970
   (set_attr "mode" "SI")])
8971
 
8972
(define_insn "*xorsi_2"
8973
  [(set (reg FLAGS_REG)
8974
        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8975
                         (match_operand:SI 2 "general_operand" "rim,ri"))
8976
                 (const_int 0)))
8977
   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8978
        (xor:SI (match_dup 1) (match_dup 2)))]
8979
  "ix86_match_ccmode (insn, CCNOmode)
8980
   && ix86_binary_operator_ok (XOR, SImode, operands)"
8981
  "xor{l}\t{%2, %0|%0, %2}"
8982
  [(set_attr "type" "alu")
8983
   (set_attr "mode" "SI")])
8984
 
8985
;; See comment for addsi_1_zext why we do use nonimmediate_operand
8986
;; ??? Special case for immediate operand is missing - it is tricky.
8987
(define_insn "*xorsi_2_zext"
8988
  [(set (reg FLAGS_REG)
8989
        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990
                         (match_operand:SI 2 "general_operand" "rim"))
8991
                 (const_int 0)))
8992
   (set (match_operand:DI 0 "register_operand" "=r")
8993
        (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8994
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8995
   && ix86_binary_operator_ok (XOR, SImode, operands)"
8996
  "xor{l}\t{%2, %k0|%k0, %2}"
8997
  [(set_attr "type" "alu")
8998
   (set_attr "mode" "SI")])
8999
 
9000
(define_insn "*xorsi_2_zext_imm"
9001
  [(set (reg FLAGS_REG)
9002
        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003
                         (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9004
                 (const_int 0)))
9005
   (set (match_operand:DI 0 "register_operand" "=r")
9006
        (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9007
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9008
   && ix86_binary_operator_ok (XOR, SImode, operands)"
9009
  "xor{l}\t{%2, %k0|%k0, %2}"
9010
  [(set_attr "type" "alu")
9011
   (set_attr "mode" "SI")])
9012
 
9013
(define_insn "*xorsi_3"
9014
  [(set (reg FLAGS_REG)
9015
        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9016
                         (match_operand:SI 2 "general_operand" "rim"))
9017
                 (const_int 0)))
9018
   (clobber (match_scratch:SI 0 "=r"))]
9019
  "ix86_match_ccmode (insn, CCNOmode)
9020
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9021
  "xor{l}\t{%2, %0|%0, %2}"
9022
  [(set_attr "type" "alu")
9023
   (set_attr "mode" "SI")])
9024
 
9025
(define_expand "xorhi3"
9026
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9027
        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9028
                (match_operand:HI 2 "general_operand" "")))
9029
   (clobber (reg:CC FLAGS_REG))]
9030
  "TARGET_HIMODE_MATH"
9031
  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9032
 
9033
(define_insn "*xorhi_1"
9034
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9035
        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9036
                (match_operand:HI 2 "general_operand" "rmi,ri")))
9037
   (clobber (reg:CC FLAGS_REG))]
9038
  "ix86_binary_operator_ok (XOR, HImode, operands)"
9039
  "xor{w}\t{%2, %0|%0, %2}"
9040
  [(set_attr "type" "alu")
9041
   (set_attr "mode" "HI")])
9042
 
9043
(define_insn "*xorhi_2"
9044
  [(set (reg FLAGS_REG)
9045
        (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9046
                         (match_operand:HI 2 "general_operand" "rim,ri"))
9047
                 (const_int 0)))
9048
   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9049
        (xor:HI (match_dup 1) (match_dup 2)))]
9050
  "ix86_match_ccmode (insn, CCNOmode)
9051
   && ix86_binary_operator_ok (XOR, HImode, operands)"
9052
  "xor{w}\t{%2, %0|%0, %2}"
9053
  [(set_attr "type" "alu")
9054
   (set_attr "mode" "HI")])
9055
 
9056
(define_insn "*xorhi_3"
9057
  [(set (reg FLAGS_REG)
9058
        (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9059
                         (match_operand:HI 2 "general_operand" "rim"))
9060
                 (const_int 0)))
9061
   (clobber (match_scratch:HI 0 "=r"))]
9062
  "ix86_match_ccmode (insn, CCNOmode)
9063
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9064
  "xor{w}\t{%2, %0|%0, %2}"
9065
  [(set_attr "type" "alu")
9066
   (set_attr "mode" "HI")])
9067
 
9068
(define_expand "xorqi3"
9069
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9070
        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9071
                (match_operand:QI 2 "general_operand" "")))
9072
   (clobber (reg:CC FLAGS_REG))]
9073
  "TARGET_QIMODE_MATH"
9074
  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9075
 
9076
;; %%% Potential partial reg stall on alternative 2.  What to do?
9077
(define_insn "*xorqi_1"
9078
  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9079
        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9080
                (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9081
   (clobber (reg:CC FLAGS_REG))]
9082
  "ix86_binary_operator_ok (XOR, QImode, operands)"
9083
  "@
9084
   xor{b}\t{%2, %0|%0, %2}
9085
   xor{b}\t{%2, %0|%0, %2}
9086
   xor{l}\t{%k2, %k0|%k0, %k2}"
9087
  [(set_attr "type" "alu")
9088
   (set_attr "mode" "QI,QI,SI")])
9089
 
9090
(define_insn "*xorqi_1_slp"
9091
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9092
        (xor:QI (match_dup 0)
9093
                (match_operand:QI 1 "general_operand" "qi,qmi")))
9094
   (clobber (reg:CC FLAGS_REG))]
9095
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9096
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9097
  "xor{b}\t{%1, %0|%0, %1}"
9098
  [(set_attr "type" "alu1")
9099
   (set_attr "mode" "QI")])
9100
 
9101
(define_insn "xorqi_ext_0"
9102
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9103
                         (const_int 8)
9104
                         (const_int 8))
9105
        (xor:SI
9106
          (zero_extract:SI
9107
            (match_operand 1 "ext_register_operand" "0")
9108
            (const_int 8)
9109
            (const_int 8))
9110
          (match_operand 2 "const_int_operand" "n")))
9111
   (clobber (reg:CC FLAGS_REG))]
9112
  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113
  "xor{b}\t{%2, %h0|%h0, %2}"
9114
  [(set_attr "type" "alu")
9115
   (set_attr "length_immediate" "1")
9116
   (set_attr "mode" "QI")])
9117
 
9118
(define_insn "*xorqi_ext_1"
9119
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120
                         (const_int 8)
9121
                         (const_int 8))
9122
        (xor:SI
9123
          (zero_extract:SI
9124
            (match_operand 1 "ext_register_operand" "0")
9125
            (const_int 8)
9126
            (const_int 8))
9127
          (zero_extend:SI
9128
            (match_operand:QI 2 "general_operand" "Qm"))))
9129
   (clobber (reg:CC FLAGS_REG))]
9130
  "!TARGET_64BIT
9131
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9132
  "xor{b}\t{%2, %h0|%h0, %2}"
9133
  [(set_attr "type" "alu")
9134
   (set_attr "length_immediate" "0")
9135
   (set_attr "mode" "QI")])
9136
 
9137
(define_insn "*xorqi_ext_1_rex64"
9138
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9139
                         (const_int 8)
9140
                         (const_int 8))
9141
        (xor:SI
9142
          (zero_extract:SI
9143
            (match_operand 1 "ext_register_operand" "0")
9144
            (const_int 8)
9145
            (const_int 8))
9146
          (zero_extend:SI
9147
            (match_operand 2 "ext_register_operand" "Q"))))
9148
   (clobber (reg:CC FLAGS_REG))]
9149
  "TARGET_64BIT
9150
   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151
  "xor{b}\t{%2, %h0|%h0, %2}"
9152
  [(set_attr "type" "alu")
9153
   (set_attr "length_immediate" "0")
9154
   (set_attr "mode" "QI")])
9155
 
9156
(define_insn "*xorqi_ext_2"
9157
  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158
                         (const_int 8)
9159
                         (const_int 8))
9160
        (xor:SI
9161
          (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9162
                           (const_int 8)
9163
                           (const_int 8))
9164
          (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9165
                           (const_int 8)
9166
                           (const_int 8))))
9167
   (clobber (reg:CC FLAGS_REG))]
9168
  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169
  "xor{b}\t{%h2, %h0|%h0, %h2}"
9170
  [(set_attr "type" "alu")
9171
   (set_attr "length_immediate" "0")
9172
   (set_attr "mode" "QI")])
9173
 
9174
(define_insn "*xorqi_cc_1"
9175
  [(set (reg FLAGS_REG)
9176
        (compare
9177
          (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9178
                  (match_operand:QI 2 "general_operand" "qim,qi"))
9179
          (const_int 0)))
9180
   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9181
        (xor:QI (match_dup 1) (match_dup 2)))]
9182
  "ix86_match_ccmode (insn, CCNOmode)
9183
   && ix86_binary_operator_ok (XOR, QImode, operands)"
9184
  "xor{b}\t{%2, %0|%0, %2}"
9185
  [(set_attr "type" "alu")
9186
   (set_attr "mode" "QI")])
9187
 
9188
(define_insn "*xorqi_2_slp"
9189
  [(set (reg FLAGS_REG)
9190
        (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9191
                         (match_operand:QI 1 "general_operand" "qim,qi"))
9192
                 (const_int 0)))
9193
   (set (strict_low_part (match_dup 0))
9194
        (xor:QI (match_dup 0) (match_dup 1)))]
9195
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196
   && ix86_match_ccmode (insn, CCNOmode)
9197
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9198
  "xor{b}\t{%1, %0|%0, %1}"
9199
  [(set_attr "type" "alu1")
9200
   (set_attr "mode" "QI")])
9201
 
9202
(define_insn "*xorqi_cc_2"
9203
  [(set (reg FLAGS_REG)
9204
        (compare
9205
          (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9206
                  (match_operand:QI 2 "general_operand" "qim"))
9207
          (const_int 0)))
9208
   (clobber (match_scratch:QI 0 "=q"))]
9209
  "ix86_match_ccmode (insn, CCNOmode)
9210
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9211
  "xor{b}\t{%2, %0|%0, %2}"
9212
  [(set_attr "type" "alu")
9213
   (set_attr "mode" "QI")])
9214
 
9215
(define_insn "*xorqi_cc_ext_1"
9216
  [(set (reg FLAGS_REG)
9217
        (compare
9218
          (xor:SI
9219
            (zero_extract:SI
9220
              (match_operand 1 "ext_register_operand" "0")
9221
              (const_int 8)
9222
              (const_int 8))
9223
            (match_operand:QI 2 "general_operand" "qmn"))
9224
          (const_int 0)))
9225
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9226
                         (const_int 8)
9227
                         (const_int 8))
9228
        (xor:SI
9229
          (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9230
          (match_dup 2)))]
9231
  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9232
  "xor{b}\t{%2, %h0|%h0, %2}"
9233
  [(set_attr "type" "alu")
9234
   (set_attr "mode" "QI")])
9235
 
9236
(define_insn "*xorqi_cc_ext_1_rex64"
9237
  [(set (reg FLAGS_REG)
9238
        (compare
9239
          (xor:SI
9240
            (zero_extract:SI
9241
              (match_operand 1 "ext_register_operand" "0")
9242
              (const_int 8)
9243
              (const_int 8))
9244
            (match_operand:QI 2 "nonmemory_operand" "Qn"))
9245
          (const_int 0)))
9246
   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9247
                         (const_int 8)
9248
                         (const_int 8))
9249
        (xor:SI
9250
          (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9251
          (match_dup 2)))]
9252
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9253
  "xor{b}\t{%2, %h0|%h0, %2}"
9254
  [(set_attr "type" "alu")
9255
   (set_attr "mode" "QI")])
9256
 
9257
(define_expand "xorqi_cc_ext_1"
9258
  [(parallel [
9259
     (set (reg:CCNO FLAGS_REG)
9260
          (compare:CCNO
9261
            (xor:SI
9262
              (zero_extract:SI
9263
                (match_operand 1 "ext_register_operand" "")
9264
                (const_int 8)
9265
                (const_int 8))
9266
              (match_operand:QI 2 "general_operand" ""))
9267
            (const_int 0)))
9268
     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9269
                           (const_int 8)
9270
                           (const_int 8))
9271
          (xor:SI
9272
            (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9273
            (match_dup 2)))])]
9274
  ""
9275
  "")
9276
 
9277
(define_split
9278
  [(set (match_operand 0 "register_operand" "")
9279
        (xor (match_operand 1 "register_operand" "")
9280
             (match_operand 2 "const_int_operand" "")))
9281
   (clobber (reg:CC FLAGS_REG))]
9282
   "reload_completed
9283
    && QI_REG_P (operands[0])
9284
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285
    && !(INTVAL (operands[2]) & ~(255 << 8))
9286
    && GET_MODE (operands[0]) != QImode"
9287
  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288
                   (xor:SI (zero_extract:SI (match_dup 1)
9289
                                            (const_int 8) (const_int 8))
9290
                           (match_dup 2)))
9291
              (clobber (reg:CC FLAGS_REG))])]
9292
  "operands[0] = gen_lowpart (SImode, operands[0]);
9293
   operands[1] = gen_lowpart (SImode, operands[1]);
9294
   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9295
 
9296
;; Since XOR can be encoded with sign extended immediate, this is only
9297
;; profitable when 7th bit is set.
9298
(define_split
9299
  [(set (match_operand 0 "register_operand" "")
9300
        (xor (match_operand 1 "general_operand" "")
9301
             (match_operand 2 "const_int_operand" "")))
9302
   (clobber (reg:CC FLAGS_REG))]
9303
   "reload_completed
9304
    && ANY_QI_REG_P (operands[0])
9305
    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306
    && !(INTVAL (operands[2]) & ~255)
9307
    && (INTVAL (operands[2]) & 128)
9308
    && GET_MODE (operands[0]) != QImode"
9309
  [(parallel [(set (strict_low_part (match_dup 0))
9310
                   (xor:QI (match_dup 1)
9311
                           (match_dup 2)))
9312
              (clobber (reg:CC FLAGS_REG))])]
9313
  "operands[0] = gen_lowpart (QImode, operands[0]);
9314
   operands[1] = gen_lowpart (QImode, operands[1]);
9315
   operands[2] = gen_lowpart (QImode, operands[2]);")
9316
 
9317
;; Negation instructions
9318
 
9319
(define_expand "negti2"
9320
  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9321
                   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9322
              (clobber (reg:CC FLAGS_REG))])]
9323
  "TARGET_64BIT"
9324
  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9325
 
9326
(define_insn "*negti2_1"
9327
  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9328
        (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9329
   (clobber (reg:CC FLAGS_REG))]
9330
  "TARGET_64BIT
9331
   && ix86_unary_operator_ok (NEG, TImode, operands)"
9332
  "#")
9333
 
9334
(define_split
9335
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9336
        (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9337
   (clobber (reg:CC FLAGS_REG))]
9338
  "TARGET_64BIT && reload_completed"
9339
  [(parallel
9340
    [(set (reg:CCZ FLAGS_REG)
9341
          (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9342
     (set (match_dup 0) (neg:DI (match_dup 2)))])
9343
   (parallel
9344
    [(set (match_dup 1)
9345
          (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9346
                            (match_dup 3))
9347
                   (const_int 0)))
9348
     (clobber (reg:CC FLAGS_REG))])
9349
   (parallel
9350
    [(set (match_dup 1)
9351
          (neg:DI (match_dup 1)))
9352
     (clobber (reg:CC FLAGS_REG))])]
9353
  "split_ti (operands+1, 1, operands+2, operands+3);
9354
   split_ti (operands+0, 1, operands+0, operands+1);")
9355
 
9356
(define_expand "negdi2"
9357
  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358
                   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9359
              (clobber (reg:CC FLAGS_REG))])]
9360
  ""
9361
  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9362
 
9363
(define_insn "*negdi2_1"
9364
  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9365
        (neg:DI (match_operand:DI 1 "general_operand" "0")))
9366
   (clobber (reg:CC FLAGS_REG))]
9367
  "!TARGET_64BIT
9368
   && ix86_unary_operator_ok (NEG, DImode, operands)"
9369
  "#")
9370
 
9371
(define_split
9372
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9373
        (neg:DI (match_operand:DI 1 "general_operand" "")))
9374
   (clobber (reg:CC FLAGS_REG))]
9375
  "!TARGET_64BIT && reload_completed"
9376
  [(parallel
9377
    [(set (reg:CCZ FLAGS_REG)
9378
          (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9379
     (set (match_dup 0) (neg:SI (match_dup 2)))])
9380
   (parallel
9381
    [(set (match_dup 1)
9382
          (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9383
                            (match_dup 3))
9384
                   (const_int 0)))
9385
     (clobber (reg:CC FLAGS_REG))])
9386
   (parallel
9387
    [(set (match_dup 1)
9388
          (neg:SI (match_dup 1)))
9389
     (clobber (reg:CC FLAGS_REG))])]
9390
  "split_di (operands+1, 1, operands+2, operands+3);
9391
   split_di (operands+0, 1, operands+0, operands+1);")
9392
 
9393
(define_insn "*negdi2_1_rex64"
9394
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9395
        (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9396
   (clobber (reg:CC FLAGS_REG))]
9397
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9398
  "neg{q}\t%0"
9399
  [(set_attr "type" "negnot")
9400
   (set_attr "mode" "DI")])
9401
 
9402
;; The problem with neg is that it does not perform (compare x 0),
9403
;; it really performs (compare 0 x), which leaves us with the zero
9404
;; flag being the only useful item.
9405
 
9406
(define_insn "*negdi2_cmpz_rex64"
9407
  [(set (reg:CCZ FLAGS_REG)
9408
        (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9409
                     (const_int 0)))
9410
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411
        (neg:DI (match_dup 1)))]
9412
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9413
  "neg{q}\t%0"
9414
  [(set_attr "type" "negnot")
9415
   (set_attr "mode" "DI")])
9416
 
9417
 
9418
(define_expand "negsi2"
9419
  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9420
                   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9421
              (clobber (reg:CC FLAGS_REG))])]
9422
  ""
9423
  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9424
 
9425
(define_insn "*negsi2_1"
9426
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427
        (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9428
   (clobber (reg:CC FLAGS_REG))]
9429
  "ix86_unary_operator_ok (NEG, SImode, operands)"
9430
  "neg{l}\t%0"
9431
  [(set_attr "type" "negnot")
9432
   (set_attr "mode" "SI")])
9433
 
9434
;; Combine is quite creative about this pattern.
9435
(define_insn "*negsi2_1_zext"
9436
  [(set (match_operand:DI 0 "register_operand" "=r")
9437
        (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9438
                                        (const_int 32)))
9439
                     (const_int 32)))
9440
   (clobber (reg:CC FLAGS_REG))]
9441
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9442
  "neg{l}\t%k0"
9443
  [(set_attr "type" "negnot")
9444
   (set_attr "mode" "SI")])
9445
 
9446
;; The problem with neg is that it does not perform (compare x 0),
9447
;; it really performs (compare 0 x), which leaves us with the zero
9448
;; flag being the only useful item.
9449
 
9450
(define_insn "*negsi2_cmpz"
9451
  [(set (reg:CCZ FLAGS_REG)
9452
        (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9453
                     (const_int 0)))
9454
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455
        (neg:SI (match_dup 1)))]
9456
  "ix86_unary_operator_ok (NEG, SImode, operands)"
9457
  "neg{l}\t%0"
9458
  [(set_attr "type" "negnot")
9459
   (set_attr "mode" "SI")])
9460
 
9461
(define_insn "*negsi2_cmpz_zext"
9462
  [(set (reg:CCZ FLAGS_REG)
9463
        (compare:CCZ (lshiftrt:DI
9464
                       (neg:DI (ashift:DI
9465
                                 (match_operand:DI 1 "register_operand" "0")
9466
                                 (const_int 32)))
9467
                       (const_int 32))
9468
                     (const_int 0)))
9469
   (set (match_operand:DI 0 "register_operand" "=r")
9470
        (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9471
                                        (const_int 32)))
9472
                     (const_int 32)))]
9473
  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9474
  "neg{l}\t%k0"
9475
  [(set_attr "type" "negnot")
9476
   (set_attr "mode" "SI")])
9477
 
9478
(define_expand "neghi2"
9479
  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9480
                   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9481
              (clobber (reg:CC FLAGS_REG))])]
9482
  "TARGET_HIMODE_MATH"
9483
  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9484
 
9485
(define_insn "*neghi2_1"
9486
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9487
        (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9488
   (clobber (reg:CC FLAGS_REG))]
9489
  "ix86_unary_operator_ok (NEG, HImode, operands)"
9490
  "neg{w}\t%0"
9491
  [(set_attr "type" "negnot")
9492
   (set_attr "mode" "HI")])
9493
 
9494
(define_insn "*neghi2_cmpz"
9495
  [(set (reg:CCZ FLAGS_REG)
9496
        (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9497
                     (const_int 0)))
9498
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9499
        (neg:HI (match_dup 1)))]
9500
  "ix86_unary_operator_ok (NEG, HImode, operands)"
9501
  "neg{w}\t%0"
9502
  [(set_attr "type" "negnot")
9503
   (set_attr "mode" "HI")])
9504
 
9505
(define_expand "negqi2"
9506
  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507
                   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9508
              (clobber (reg:CC FLAGS_REG))])]
9509
  "TARGET_QIMODE_MATH"
9510
  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9511
 
9512
(define_insn "*negqi2_1"
9513
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9514
        (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9515
   (clobber (reg:CC FLAGS_REG))]
9516
  "ix86_unary_operator_ok (NEG, QImode, operands)"
9517
  "neg{b}\t%0"
9518
  [(set_attr "type" "negnot")
9519
   (set_attr "mode" "QI")])
9520
 
9521
(define_insn "*negqi2_cmpz"
9522
  [(set (reg:CCZ FLAGS_REG)
9523
        (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9524
                     (const_int 0)))
9525
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9526
        (neg:QI (match_dup 1)))]
9527
  "ix86_unary_operator_ok (NEG, QImode, operands)"
9528
  "neg{b}\t%0"
9529
  [(set_attr "type" "negnot")
9530
   (set_attr "mode" "QI")])
9531
 
9532
;; Changing of sign for FP values is doable using integer unit too.
9533
 
9534
(define_expand "negsf2"
9535
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9536
        (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9537
  "TARGET_80387 || TARGET_SSE_MATH"
9538
  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9539
 
9540
(define_expand "abssf2"
9541
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9542
        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9543
  "TARGET_80387 || TARGET_SSE_MATH"
9544
  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9545
 
9546
(define_insn "*absnegsf2_mixed"
9547
  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9548
        (match_operator:SF 3 "absneg_operator"
9549
          [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9550
   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9551
   (clobber (reg:CC FLAGS_REG))]
9552
  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9553
   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9554
  "#")
9555
 
9556
(define_insn "*absnegsf2_sse"
9557
  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9558
        (match_operator:SF 3 "absneg_operator"
9559
          [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9560
   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9561
   (clobber (reg:CC FLAGS_REG))]
9562
  "TARGET_SSE_MATH
9563
   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9564
  "#")
9565
 
9566
(define_insn "*absnegsf2_i387"
9567
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9568
        (match_operator:SF 3 "absneg_operator"
9569
          [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9570
   (use (match_operand 2 "" ""))
9571
   (clobber (reg:CC FLAGS_REG))]
9572
  "TARGET_80387 && !TARGET_SSE_MATH
9573
   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9574
  "#")
9575
 
9576
(define_expand "copysignsf3"
9577
  [(match_operand:SF 0 "register_operand" "")
9578
   (match_operand:SF 1 "nonmemory_operand" "")
9579
   (match_operand:SF 2 "register_operand" "")]
9580
  "TARGET_SSE_MATH"
9581
{
9582
  ix86_expand_copysign (operands);
9583
  DONE;
9584
})
9585
 
9586
(define_insn_and_split "copysignsf3_const"
9587
  [(set (match_operand:SF 0 "register_operand"          "=x")
9588
        (unspec:SF
9589
          [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9590
           (match_operand:SF 2 "register_operand"       "0")
9591
           (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9592
          UNSPEC_COPYSIGN))]
9593
  "TARGET_SSE_MATH"
9594
  "#"
9595
  "&& reload_completed"
9596
  [(const_int 0)]
9597
{
9598
  ix86_split_copysign_const (operands);
9599
  DONE;
9600
})
9601
 
9602
(define_insn "copysignsf3_var"
9603
  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9604
        (unspec:SF
9605
          [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9606
           (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9607
           (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9608
           (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9609
          UNSPEC_COPYSIGN))
9610
   (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9611
  "TARGET_SSE_MATH"
9612
  "#")
9613
 
9614
(define_split
9615
  [(set (match_operand:SF 0 "register_operand" "")
9616
        (unspec:SF
9617
          [(match_operand:SF 2 "register_operand" "")
9618
           (match_operand:SF 3 "register_operand" "")
9619
           (match_operand:V4SF 4 "" "")
9620
           (match_operand:V4SF 5 "" "")]
9621
          UNSPEC_COPYSIGN))
9622
   (clobber (match_scratch:V4SF 1 ""))]
9623
  "TARGET_SSE_MATH && reload_completed"
9624
  [(const_int 0)]
9625
{
9626
  ix86_split_copysign_var (operands);
9627
  DONE;
9628
})
9629
 
9630
(define_expand "negdf2"
9631
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632
        (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634
  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635
 
9636
(define_expand "absdf2"
9637
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638
        (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639
  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640
  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
 
9642
(define_insn "*absnegdf2_mixed"
9643
  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9644
        (match_operator:DF 3 "absneg_operator"
9645
          [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9646
   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9647
   (clobber (reg:CC FLAGS_REG))]
9648
  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649
   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650
  "#")
9651
 
9652
(define_insn "*absnegdf2_sse"
9653
  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9654
        (match_operator:DF 3 "absneg_operator"
9655
          [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9656
   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9657
   (clobber (reg:CC FLAGS_REG))]
9658
  "TARGET_SSE2 && TARGET_SSE_MATH
9659
   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660
  "#")
9661
 
9662
(define_insn "*absnegdf2_i387"
9663
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9664
        (match_operator:DF 3 "absneg_operator"
9665
          [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666
   (use (match_operand 2 "" ""))
9667
   (clobber (reg:CC FLAGS_REG))]
9668
  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669
   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670
  "#")
9671
 
9672
(define_expand "copysigndf3"
9673
  [(match_operand:DF 0 "register_operand" "")
9674
   (match_operand:DF 1 "nonmemory_operand" "")
9675
   (match_operand:DF 2 "register_operand" "")]
9676
  "TARGET_SSE2 && TARGET_SSE_MATH"
9677
{
9678
  ix86_expand_copysign (operands);
9679
  DONE;
9680
})
9681
 
9682
(define_insn_and_split "copysigndf3_const"
9683
  [(set (match_operand:DF 0 "register_operand"          "=x")
9684
        (unspec:DF
9685
          [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9686
           (match_operand:DF 2 "register_operand"       "0")
9687
           (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9688
          UNSPEC_COPYSIGN))]
9689
  "TARGET_SSE2 && TARGET_SSE_MATH"
9690
  "#"
9691
  "&& reload_completed"
9692
  [(const_int 0)]
9693
{
9694
  ix86_split_copysign_const (operands);
9695
  DONE;
9696
})
9697
 
9698
(define_insn "copysigndf3_var"
9699
  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9700
        (unspec:DF
9701
          [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9702
           (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9703
           (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9704
           (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9705
          UNSPEC_COPYSIGN))
9706
   (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9707
  "TARGET_SSE2 && TARGET_SSE_MATH"
9708
  "#")
9709
 
9710
(define_split
9711
  [(set (match_operand:DF 0 "register_operand" "")
9712
        (unspec:DF
9713
          [(match_operand:DF 2 "register_operand" "")
9714
           (match_operand:DF 3 "register_operand" "")
9715
           (match_operand:V2DF 4 "" "")
9716
           (match_operand:V2DF 5 "" "")]
9717
          UNSPEC_COPYSIGN))
9718
   (clobber (match_scratch:V2DF 1 ""))]
9719
  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9720
  [(const_int 0)]
9721
{
9722
  ix86_split_copysign_var (operands);
9723
  DONE;
9724
})
9725
 
9726
(define_expand "negxf2"
9727
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9728
        (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9729
  "TARGET_80387"
9730
  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9731
 
9732
(define_expand "absxf2"
9733
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9734
        (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9735
  "TARGET_80387"
9736
  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9737
 
9738
(define_insn "*absnegxf2_i387"
9739
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9740
        (match_operator:XF 3 "absneg_operator"
9741
          [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9742
   (use (match_operand 2 "" ""))
9743
   (clobber (reg:CC FLAGS_REG))]
9744
  "TARGET_80387
9745
   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9746
  "#")
9747
 
9748
;; Splitters for fp abs and neg.
9749
 
9750
(define_split
9751
  [(set (match_operand 0 "fp_register_operand" "")
9752
        (match_operator 1 "absneg_operator" [(match_dup 0)]))
9753
   (use (match_operand 2 "" ""))
9754
   (clobber (reg:CC FLAGS_REG))]
9755
  "reload_completed"
9756
  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9757
 
9758
(define_split
9759
  [(set (match_operand 0 "register_operand" "")
9760
        (match_operator 3 "absneg_operator"
9761
          [(match_operand 1 "register_operand" "")]))
9762
   (use (match_operand 2 "nonimmediate_operand" ""))
9763
   (clobber (reg:CC FLAGS_REG))]
9764
  "reload_completed && SSE_REG_P (operands[0])"
9765
  [(set (match_dup 0) (match_dup 3))]
9766
{
9767
  enum machine_mode mode = GET_MODE (operands[0]);
9768
  enum machine_mode vmode = GET_MODE (operands[2]);
9769
  rtx tmp;
9770
 
9771
  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9772
  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9773
  if (operands_match_p (operands[0], operands[2]))
9774
    {
9775
      tmp = operands[1];
9776
      operands[1] = operands[2];
9777
      operands[2] = tmp;
9778
    }
9779
  if (GET_CODE (operands[3]) == ABS)
9780
    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9781
  else
9782
    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9783
  operands[3] = tmp;
9784
})
9785
 
9786
(define_split
9787
  [(set (match_operand:SF 0 "register_operand" "")
9788
        (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9789
   (use (match_operand:V4SF 2 "" ""))
9790
   (clobber (reg:CC FLAGS_REG))]
9791
  "reload_completed"
9792
  [(parallel [(set (match_dup 0) (match_dup 1))
9793
              (clobber (reg:CC FLAGS_REG))])]
9794
{
9795
  rtx tmp;
9796
  operands[0] = gen_lowpart (SImode, operands[0]);
9797
  if (GET_CODE (operands[1]) == ABS)
9798
    {
9799
      tmp = gen_int_mode (0x7fffffff, SImode);
9800
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9801
    }
9802
  else
9803
    {
9804
      tmp = gen_int_mode (0x80000000, SImode);
9805
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9806
    }
9807
  operands[1] = tmp;
9808
})
9809
 
9810
(define_split
9811
  [(set (match_operand:DF 0 "register_operand" "")
9812
        (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9813
   (use (match_operand 2 "" ""))
9814
   (clobber (reg:CC FLAGS_REG))]
9815
  "reload_completed"
9816
  [(parallel [(set (match_dup 0) (match_dup 1))
9817
              (clobber (reg:CC FLAGS_REG))])]
9818
{
9819
  rtx tmp;
9820
  if (TARGET_64BIT)
9821
    {
9822
      tmp = gen_lowpart (DImode, operands[0]);
9823
      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9824
      operands[0] = tmp;
9825
 
9826
      if (GET_CODE (operands[1]) == ABS)
9827
        tmp = const0_rtx;
9828
      else
9829
        tmp = gen_rtx_NOT (DImode, tmp);
9830
    }
9831
  else
9832
    {
9833
      operands[0] = gen_highpart (SImode, operands[0]);
9834
      if (GET_CODE (operands[1]) == ABS)
9835
        {
9836
          tmp = gen_int_mode (0x7fffffff, SImode);
9837
          tmp = gen_rtx_AND (SImode, operands[0], tmp);
9838
        }
9839
      else
9840
        {
9841
          tmp = gen_int_mode (0x80000000, SImode);
9842
          tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9843
        }
9844
    }
9845
  operands[1] = tmp;
9846
})
9847
 
9848
(define_split
9849
  [(set (match_operand:XF 0 "register_operand" "")
9850
        (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9851
   (use (match_operand 2 "" ""))
9852
   (clobber (reg:CC FLAGS_REG))]
9853
  "reload_completed"
9854
  [(parallel [(set (match_dup 0) (match_dup 1))
9855
              (clobber (reg:CC FLAGS_REG))])]
9856
{
9857
  rtx tmp;
9858
  operands[0] = gen_rtx_REG (SImode,
9859
                             true_regnum (operands[0])
9860
                             + (TARGET_64BIT ? 1 : 2));
9861
  if (GET_CODE (operands[1]) == ABS)
9862
    {
9863
      tmp = GEN_INT (0x7fff);
9864
      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9865
    }
9866
  else
9867
    {
9868
      tmp = GEN_INT (0x8000);
9869
      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9870
    }
9871
  operands[1] = tmp;
9872
})
9873
 
9874
(define_split
9875
  [(set (match_operand 0 "memory_operand" "")
9876
        (match_operator 1 "absneg_operator" [(match_dup 0)]))
9877
   (use (match_operand 2 "" ""))
9878
   (clobber (reg:CC FLAGS_REG))]
9879
  "reload_completed"
9880
  [(parallel [(set (match_dup 0) (match_dup 1))
9881
              (clobber (reg:CC FLAGS_REG))])]
9882
{
9883
  enum machine_mode mode = GET_MODE (operands[0]);
9884
  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9885
  rtx tmp;
9886
 
9887
  operands[0] = adjust_address (operands[0], QImode, size - 1);
9888
  if (GET_CODE (operands[1]) == ABS)
9889
    {
9890
      tmp = gen_int_mode (0x7f, QImode);
9891
      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9892
    }
9893
  else
9894
    {
9895
      tmp = gen_int_mode (0x80, QImode);
9896
      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9897
    }
9898
  operands[1] = tmp;
9899
})
9900
 
9901
;; Conditionalize these after reload. If they match before reload, we
9902
;; lose the clobber and ability to use integer instructions.
9903
 
9904
(define_insn "*negsf2_1"
9905
  [(set (match_operand:SF 0 "register_operand" "=f")
9906
        (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9907
  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9908
  "fchs"
9909
  [(set_attr "type" "fsgn")
9910
   (set_attr "mode" "SF")])
9911
 
9912
(define_insn "*negdf2_1"
9913
  [(set (match_operand:DF 0 "register_operand" "=f")
9914
        (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9915
  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9916
  "fchs"
9917
  [(set_attr "type" "fsgn")
9918
   (set_attr "mode" "DF")])
9919
 
9920
(define_insn "*negxf2_1"
9921
  [(set (match_operand:XF 0 "register_operand" "=f")
9922
        (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9923
  "TARGET_80387"
9924
  "fchs"
9925
  [(set_attr "type" "fsgn")
9926
   (set_attr "mode" "XF")])
9927
 
9928
(define_insn "*abssf2_1"
9929
  [(set (match_operand:SF 0 "register_operand" "=f")
9930
        (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9931
  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9932
  "fabs"
9933
  [(set_attr "type" "fsgn")
9934
   (set_attr "mode" "SF")])
9935
 
9936
(define_insn "*absdf2_1"
9937
  [(set (match_operand:DF 0 "register_operand" "=f")
9938
        (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9939
  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9940
  "fabs"
9941
  [(set_attr "type" "fsgn")
9942
   (set_attr "mode" "DF")])
9943
 
9944
(define_insn "*absxf2_1"
9945
  [(set (match_operand:XF 0 "register_operand" "=f")
9946
        (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9947
  "TARGET_80387"
9948
  "fabs"
9949
  [(set_attr "type" "fsgn")
9950
   (set_attr "mode" "DF")])
9951
 
9952
(define_insn "*negextendsfdf2"
9953
  [(set (match_operand:DF 0 "register_operand" "=f")
9954
        (neg:DF (float_extend:DF
9955
                  (match_operand:SF 1 "register_operand" "0"))))]
9956
  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9957
  "fchs"
9958
  [(set_attr "type" "fsgn")
9959
   (set_attr "mode" "DF")])
9960
 
9961
(define_insn "*negextenddfxf2"
9962
  [(set (match_operand:XF 0 "register_operand" "=f")
9963
        (neg:XF (float_extend:XF
9964
                  (match_operand:DF 1 "register_operand" "0"))))]
9965
  "TARGET_80387"
9966
  "fchs"
9967
  [(set_attr "type" "fsgn")
9968
   (set_attr "mode" "XF")])
9969
 
9970
(define_insn "*negextendsfxf2"
9971
  [(set (match_operand:XF 0 "register_operand" "=f")
9972
        (neg:XF (float_extend:XF
9973
                  (match_operand:SF 1 "register_operand" "0"))))]
9974
  "TARGET_80387"
9975
  "fchs"
9976
  [(set_attr "type" "fsgn")
9977
   (set_attr "mode" "XF")])
9978
 
9979
(define_insn "*absextendsfdf2"
9980
  [(set (match_operand:DF 0 "register_operand" "=f")
9981
        (abs:DF (float_extend:DF
9982
                  (match_operand:SF 1 "register_operand" "0"))))]
9983
  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9984
  "fabs"
9985
  [(set_attr "type" "fsgn")
9986
   (set_attr "mode" "DF")])
9987
 
9988
(define_insn "*absextenddfxf2"
9989
  [(set (match_operand:XF 0 "register_operand" "=f")
9990
        (abs:XF (float_extend:XF
9991
          (match_operand:DF 1 "register_operand" "0"))))]
9992
  "TARGET_80387"
9993
  "fabs"
9994
  [(set_attr "type" "fsgn")
9995
   (set_attr "mode" "XF")])
9996
 
9997
(define_insn "*absextendsfxf2"
9998
  [(set (match_operand:XF 0 "register_operand" "=f")
9999
        (abs:XF (float_extend:XF
10000
          (match_operand:SF 1 "register_operand" "0"))))]
10001
  "TARGET_80387"
10002
  "fabs"
10003
  [(set_attr "type" "fsgn")
10004
   (set_attr "mode" "XF")])
10005
 
10006
;; One complement instructions
10007
 
10008
(define_expand "one_cmpldi2"
10009
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10010
        (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10011
  "TARGET_64BIT"
10012
  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10013
 
10014
(define_insn "*one_cmpldi2_1_rex64"
10015
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10016
        (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10017
  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10018
  "not{q}\t%0"
10019
  [(set_attr "type" "negnot")
10020
   (set_attr "mode" "DI")])
10021
 
10022
(define_insn "*one_cmpldi2_2_rex64"
10023
  [(set (reg FLAGS_REG)
10024
        (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10025
                 (const_int 0)))
10026
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10027
        (not:DI (match_dup 1)))]
10028
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10029
   && ix86_unary_operator_ok (NOT, DImode, operands)"
10030
  "#"
10031
  [(set_attr "type" "alu1")
10032
   (set_attr "mode" "DI")])
10033
 
10034
(define_split
10035
  [(set (match_operand 0 "flags_reg_operand" "")
10036
        (match_operator 2 "compare_operator"
10037
          [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10038
           (const_int 0)]))
10039
   (set (match_operand:DI 1 "nonimmediate_operand" "")
10040
        (not:DI (match_dup 3)))]
10041
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042
  [(parallel [(set (match_dup 0)
10043
                   (match_op_dup 2
10044
                     [(xor:DI (match_dup 3) (const_int -1))
10045
                      (const_int 0)]))
10046
              (set (match_dup 1)
10047
                   (xor:DI (match_dup 3) (const_int -1)))])]
10048
  "")
10049
 
10050
(define_expand "one_cmplsi2"
10051
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10052
        (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10053
  ""
10054
  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10055
 
10056
(define_insn "*one_cmplsi2_1"
10057
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10058
        (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10059
  "ix86_unary_operator_ok (NOT, SImode, operands)"
10060
  "not{l}\t%0"
10061
  [(set_attr "type" "negnot")
10062
   (set_attr "mode" "SI")])
10063
 
10064
;; ??? Currently never generated - xor is used instead.
10065
(define_insn "*one_cmplsi2_1_zext"
10066
  [(set (match_operand:DI 0 "register_operand" "=r")
10067
        (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10068
  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10069
  "not{l}\t%k0"
10070
  [(set_attr "type" "negnot")
10071
   (set_attr "mode" "SI")])
10072
 
10073
(define_insn "*one_cmplsi2_2"
10074
  [(set (reg FLAGS_REG)
10075
        (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10076
                 (const_int 0)))
10077
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10078
        (not:SI (match_dup 1)))]
10079
  "ix86_match_ccmode (insn, CCNOmode)
10080
   && ix86_unary_operator_ok (NOT, SImode, operands)"
10081
  "#"
10082
  [(set_attr "type" "alu1")
10083
   (set_attr "mode" "SI")])
10084
 
10085
(define_split
10086
  [(set (match_operand 0 "flags_reg_operand" "")
10087
        (match_operator 2 "compare_operator"
10088
          [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10089
           (const_int 0)]))
10090
   (set (match_operand:SI 1 "nonimmediate_operand" "")
10091
        (not:SI (match_dup 3)))]
10092
  "ix86_match_ccmode (insn, CCNOmode)"
10093
  [(parallel [(set (match_dup 0)
10094
                   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095
                                    (const_int 0)]))
10096
              (set (match_dup 1)
10097
                   (xor:SI (match_dup 3) (const_int -1)))])]
10098
  "")
10099
 
10100
;; ??? Currently never generated - xor is used instead.
10101
(define_insn "*one_cmplsi2_2_zext"
10102
  [(set (reg FLAGS_REG)
10103
        (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10104
                 (const_int 0)))
10105
   (set (match_operand:DI 0 "register_operand" "=r")
10106
        (zero_extend:DI (not:SI (match_dup 1))))]
10107
  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10108
   && ix86_unary_operator_ok (NOT, SImode, operands)"
10109
  "#"
10110
  [(set_attr "type" "alu1")
10111
   (set_attr "mode" "SI")])
10112
 
10113
(define_split
10114
  [(set (match_operand 0 "flags_reg_operand" "")
10115
        (match_operator 2 "compare_operator"
10116
          [(not:SI (match_operand:SI 3 "register_operand" ""))
10117
           (const_int 0)]))
10118
   (set (match_operand:DI 1 "register_operand" "")
10119
        (zero_extend:DI (not:SI (match_dup 3))))]
10120
  "ix86_match_ccmode (insn, CCNOmode)"
10121
  [(parallel [(set (match_dup 0)
10122
                   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10123
                                    (const_int 0)]))
10124
              (set (match_dup 1)
10125
                   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10126
  "")
10127
 
10128
(define_expand "one_cmplhi2"
10129
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10130
        (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10131
  "TARGET_HIMODE_MATH"
10132
  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10133
 
10134
(define_insn "*one_cmplhi2_1"
10135
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10136
        (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10137
  "ix86_unary_operator_ok (NOT, HImode, operands)"
10138
  "not{w}\t%0"
10139
  [(set_attr "type" "negnot")
10140
   (set_attr "mode" "HI")])
10141
 
10142
(define_insn "*one_cmplhi2_2"
10143
  [(set (reg FLAGS_REG)
10144
        (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10145
                 (const_int 0)))
10146
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10147
        (not:HI (match_dup 1)))]
10148
  "ix86_match_ccmode (insn, CCNOmode)
10149
   && ix86_unary_operator_ok (NEG, HImode, operands)"
10150
  "#"
10151
  [(set_attr "type" "alu1")
10152
   (set_attr "mode" "HI")])
10153
 
10154
(define_split
10155
  [(set (match_operand 0 "flags_reg_operand" "")
10156
        (match_operator 2 "compare_operator"
10157
          [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10158
           (const_int 0)]))
10159
   (set (match_operand:HI 1 "nonimmediate_operand" "")
10160
        (not:HI (match_dup 3)))]
10161
  "ix86_match_ccmode (insn, CCNOmode)"
10162
  [(parallel [(set (match_dup 0)
10163
                   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10164
                                    (const_int 0)]))
10165
              (set (match_dup 1)
10166
                   (xor:HI (match_dup 3) (const_int -1)))])]
10167
  "")
10168
 
10169
;; %%% Potential partial reg stall on alternative 1.  What to do?
10170
(define_expand "one_cmplqi2"
10171
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10172
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10173
  "TARGET_QIMODE_MATH"
10174
  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10175
 
10176
(define_insn "*one_cmplqi2_1"
10177
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10178
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10179
  "ix86_unary_operator_ok (NOT, QImode, operands)"
10180
  "@
10181
   not{b}\t%0
10182
   not{l}\t%k0"
10183
  [(set_attr "type" "negnot")
10184
   (set_attr "mode" "QI,SI")])
10185
 
10186
(define_insn "*one_cmplqi2_2"
10187
  [(set (reg FLAGS_REG)
10188
        (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10189
                 (const_int 0)))
10190
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10191
        (not:QI (match_dup 1)))]
10192
  "ix86_match_ccmode (insn, CCNOmode)
10193
   && ix86_unary_operator_ok (NOT, QImode, operands)"
10194
  "#"
10195
  [(set_attr "type" "alu1")
10196
   (set_attr "mode" "QI")])
10197
 
10198
(define_split
10199
  [(set (match_operand 0 "flags_reg_operand" "")
10200
        (match_operator 2 "compare_operator"
10201
          [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10202
           (const_int 0)]))
10203
   (set (match_operand:QI 1 "nonimmediate_operand" "")
10204
        (not:QI (match_dup 3)))]
10205
  "ix86_match_ccmode (insn, CCNOmode)"
10206
  [(parallel [(set (match_dup 0)
10207
                   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10208
                                    (const_int 0)]))
10209
              (set (match_dup 1)
10210
                   (xor:QI (match_dup 3) (const_int -1)))])]
10211
  "")
10212
 
10213
;; Arithmetic shift instructions
10214
 
10215
;; DImode shifts are implemented using the i386 "shift double" opcode,
10216
;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10217
;; is variable, then the count is in %cl and the "imm" operand is dropped
10218
;; from the assembler input.
10219
;;
10220
;; This instruction shifts the target reg/mem as usual, but instead of
10221
;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10222
;; is a left shift double, bits are taken from the high order bits of
10223
;; reg, else if the insn is a shift right double, bits are taken from the
10224
;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10225
;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10226
;;
10227
;; Since sh[lr]d does not change the `reg' operand, that is done
10228
;; separately, making all shifts emit pairs of shift double and normal
10229
;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10230
;; support a 63 bit shift, each shift where the count is in a reg expands
10231
;; to a pair of shifts, a branch, a shift by 32 and a label.
10232
;;
10233
;; If the shift count is a constant, we need never emit more than one
10234
;; shift pair, instead using moves and sign extension for counts greater
10235
;; than 31.
10236
 
10237
(define_expand "ashlti3"
10238
  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10239
                   (ashift:TI (match_operand:TI 1 "register_operand" "")
10240
                              (match_operand:QI 2 "nonmemory_operand" "")))
10241
              (clobber (reg:CC FLAGS_REG))])]
10242
  "TARGET_64BIT"
10243
{
10244
  if (! immediate_operand (operands[2], QImode))
10245
    {
10246
      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10247
      DONE;
10248
    }
10249
  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10250
  DONE;
10251
})
10252
 
10253
(define_insn "ashlti3_1"
10254
  [(set (match_operand:TI 0 "register_operand" "=r")
10255
        (ashift:TI (match_operand:TI 1 "register_operand" "0")
10256
                   (match_operand:QI 2 "register_operand" "c")))
10257
   (clobber (match_scratch:DI 3 "=&r"))
10258
   (clobber (reg:CC FLAGS_REG))]
10259
  "TARGET_64BIT"
10260
  "#"
10261
  [(set_attr "type" "multi")])
10262
 
10263
(define_insn "*ashlti3_2"
10264
  [(set (match_operand:TI 0 "register_operand" "=r")
10265
        (ashift:TI (match_operand:TI 1 "register_operand" "0")
10266
                   (match_operand:QI 2 "immediate_operand" "O")))
10267
   (clobber (reg:CC FLAGS_REG))]
10268
  "TARGET_64BIT"
10269
  "#"
10270
  [(set_attr "type" "multi")])
10271
 
10272
(define_split
10273
  [(set (match_operand:TI 0 "register_operand" "")
10274
        (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10275
                   (match_operand:QI 2 "register_operand" "")))
10276
   (clobber (match_scratch:DI 3 ""))
10277
   (clobber (reg:CC FLAGS_REG))]
10278
  "TARGET_64BIT && reload_completed"
10279
  [(const_int 0)]
10280
  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10281
 
10282
(define_split
10283
  [(set (match_operand:TI 0 "register_operand" "")
10284
        (ashift:TI (match_operand:TI 1 "register_operand" "")
10285
                   (match_operand:QI 2 "immediate_operand" "")))
10286
   (clobber (reg:CC FLAGS_REG))]
10287
  "TARGET_64BIT && reload_completed"
10288
  [(const_int 0)]
10289
  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10290
 
10291
(define_insn "x86_64_shld"
10292
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10293
        (ior:DI (ashift:DI (match_dup 0)
10294
                  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10295
                (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10296
                  (minus:QI (const_int 64) (match_dup 2)))))
10297
   (clobber (reg:CC FLAGS_REG))]
10298
  "TARGET_64BIT"
10299
  "@
10300
   shld{q}\t{%2, %1, %0|%0, %1, %2}
10301
   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10302
  [(set_attr "type" "ishift")
10303
   (set_attr "prefix_0f" "1")
10304
   (set_attr "mode" "DI")
10305
   (set_attr "athlon_decode" "vector")])
10306
 
10307
(define_expand "x86_64_shift_adj"
10308
  [(set (reg:CCZ FLAGS_REG)
10309
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10310
                             (const_int 64))
10311
                     (const_int 0)))
10312
   (set (match_operand:DI 0 "register_operand" "")
10313
        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10314
                         (match_operand:DI 1 "register_operand" "")
10315
                         (match_dup 0)))
10316
   (set (match_dup 1)
10317
        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10318
                         (match_operand:DI 3 "register_operand" "r")
10319
                         (match_dup 1)))]
10320
  "TARGET_64BIT"
10321
  "")
10322
 
10323
(define_expand "ashldi3"
10324
  [(set (match_operand:DI 0 "shiftdi_operand" "")
10325
        (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10326
                   (match_operand:QI 2 "nonmemory_operand" "")))]
10327
  ""
10328
  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10329
 
10330
(define_insn "*ashldi3_1_rex64"
10331
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10332
        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10333
                   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10334
   (clobber (reg:CC FLAGS_REG))]
10335
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10336
{
10337
  switch (get_attr_type (insn))
10338
    {
10339
    case TYPE_ALU:
10340
      gcc_assert (operands[2] == const1_rtx);
10341
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10342
      return "add{q}\t{%0, %0|%0, %0}";
10343
 
10344
    case TYPE_LEA:
10345
      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10346
      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10347
      operands[1] = gen_rtx_MULT (DImode, operands[1],
10348
                                  GEN_INT (1 << INTVAL (operands[2])));
10349
      return "lea{q}\t{%a1, %0|%0, %a1}";
10350
 
10351
    default:
10352
      if (REG_P (operands[2]))
10353
        return "sal{q}\t{%b2, %0|%0, %b2}";
10354
      else if (operands[2] == const1_rtx
10355
               && (TARGET_SHIFT1 || optimize_size))
10356
        return "sal{q}\t%0";
10357
      else
10358
        return "sal{q}\t{%2, %0|%0, %2}";
10359
    }
10360
}
10361
  [(set (attr "type")
10362
     (cond [(eq_attr "alternative" "1")
10363
              (const_string "lea")
10364
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10365
                          (const_int 0))
10366
                      (match_operand 0 "register_operand" ""))
10367
                 (match_operand 2 "const1_operand" ""))
10368
              (const_string "alu")
10369
           ]
10370
           (const_string "ishift")))
10371
   (set_attr "mode" "DI")])
10372
 
10373
;; Convert lea to the lea pattern to avoid flags dependency.
10374
(define_split
10375
  [(set (match_operand:DI 0 "register_operand" "")
10376
        (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10377
                   (match_operand:QI 2 "immediate_operand" "")))
10378
   (clobber (reg:CC FLAGS_REG))]
10379
  "TARGET_64BIT && reload_completed
10380
   && true_regnum (operands[0]) != true_regnum (operands[1])"
10381
  [(set (match_dup 0)
10382
        (mult:DI (match_dup 1)
10383
                 (match_dup 2)))]
10384
  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10385
 
10386
;; This pattern can't accept a variable shift count, since shifts by
10387
;; zero don't affect the flags.  We assume that shifts by constant
10388
;; zero are optimized away.
10389
(define_insn "*ashldi3_cmp_rex64"
10390
  [(set (reg FLAGS_REG)
10391
        (compare
10392
          (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10393
                     (match_operand:QI 2 "immediate_operand" "e"))
10394
          (const_int 0)))
10395
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10396
        (ashift:DI (match_dup 1) (match_dup 2)))]
10397
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10398
   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10399
   && (optimize_size
10400
       || !TARGET_PARTIAL_FLAG_REG_STALL
10401
       || (operands[2] == const1_rtx
10402
           && (TARGET_SHIFT1
10403
               || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10404
{
10405
  switch (get_attr_type (insn))
10406
    {
10407
    case TYPE_ALU:
10408
      gcc_assert (operands[2] == const1_rtx);
10409
      return "add{q}\t{%0, %0|%0, %0}";
10410
 
10411
    default:
10412
      if (REG_P (operands[2]))
10413
        return "sal{q}\t{%b2, %0|%0, %b2}";
10414
      else if (operands[2] == const1_rtx
10415
               && (TARGET_SHIFT1 || optimize_size))
10416
        return "sal{q}\t%0";
10417
      else
10418
        return "sal{q}\t{%2, %0|%0, %2}";
10419
    }
10420
}
10421
  [(set (attr "type")
10422
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10423
                          (const_int 0))
10424
                      (match_operand 0 "register_operand" ""))
10425
                 (match_operand 2 "const1_operand" ""))
10426
              (const_string "alu")
10427
           ]
10428
           (const_string "ishift")))
10429
   (set_attr "mode" "DI")])
10430
 
10431
(define_insn "*ashldi3_cconly_rex64"
10432
  [(set (reg FLAGS_REG)
10433
        (compare
10434
          (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10435
                     (match_operand:QI 2 "immediate_operand" "e"))
10436
          (const_int 0)))
10437
   (clobber (match_scratch:DI 0 "=r"))]
10438
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10439
   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10440
   && (optimize_size
10441
       || !TARGET_PARTIAL_FLAG_REG_STALL
10442
       || (operands[2] == const1_rtx
10443
           && (TARGET_SHIFT1
10444
               || TARGET_DOUBLE_WITH_ADD)))"
10445
{
10446
  switch (get_attr_type (insn))
10447
    {
10448
    case TYPE_ALU:
10449
      gcc_assert (operands[2] == const1_rtx);
10450
      return "add{q}\t{%0, %0|%0, %0}";
10451
 
10452
    default:
10453
      if (REG_P (operands[2]))
10454
        return "sal{q}\t{%b2, %0|%0, %b2}";
10455
      else if (operands[2] == const1_rtx
10456
               && (TARGET_SHIFT1 || optimize_size))
10457
        return "sal{q}\t%0";
10458
      else
10459
        return "sal{q}\t{%2, %0|%0, %2}";
10460
    }
10461
}
10462
  [(set (attr "type")
10463
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10464
                          (const_int 0))
10465
                      (match_operand 0 "register_operand" ""))
10466
                 (match_operand 2 "const1_operand" ""))
10467
              (const_string "alu")
10468
           ]
10469
           (const_string "ishift")))
10470
   (set_attr "mode" "DI")])
10471
 
10472
(define_insn "*ashldi3_1"
10473
  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10474
        (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10475
                   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10476
   (clobber (reg:CC FLAGS_REG))]
10477
  "!TARGET_64BIT"
10478
  "#"
10479
  [(set_attr "type" "multi")])
10480
 
10481
;; By default we don't ask for a scratch register, because when DImode
10482
;; values are manipulated, registers are already at a premium.  But if
10483
;; we have one handy, we won't turn it away.
10484
(define_peephole2
10485
  [(match_scratch:SI 3 "r")
10486
   (parallel [(set (match_operand:DI 0 "register_operand" "")
10487
                   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10488
                              (match_operand:QI 2 "nonmemory_operand" "")))
10489
              (clobber (reg:CC FLAGS_REG))])
10490
   (match_dup 3)]
10491
  "!TARGET_64BIT && TARGET_CMOVE"
10492
  [(const_int 0)]
10493
  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10494
 
10495
(define_split
10496
  [(set (match_operand:DI 0 "register_operand" "")
10497
        (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10498
                   (match_operand:QI 2 "nonmemory_operand" "")))
10499
   (clobber (reg:CC FLAGS_REG))]
10500
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10501
                     ? flow2_completed : reload_completed)"
10502
  [(const_int 0)]
10503
  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10504
 
10505
(define_insn "x86_shld_1"
10506
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10507
        (ior:SI (ashift:SI (match_dup 0)
10508
                  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10509
                (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10510
                  (minus:QI (const_int 32) (match_dup 2)))))
10511
   (clobber (reg:CC FLAGS_REG))]
10512
  ""
10513
  "@
10514
   shld{l}\t{%2, %1, %0|%0, %1, %2}
10515
   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10516
  [(set_attr "type" "ishift")
10517
   (set_attr "prefix_0f" "1")
10518
   (set_attr "mode" "SI")
10519
   (set_attr "pent_pair" "np")
10520
   (set_attr "athlon_decode" "vector")])
10521
 
10522
(define_expand "x86_shift_adj_1"
10523
  [(set (reg:CCZ FLAGS_REG)
10524
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10525
                             (const_int 32))
10526
                     (const_int 0)))
10527
   (set (match_operand:SI 0 "register_operand" "")
10528
        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10529
                         (match_operand:SI 1 "register_operand" "")
10530
                         (match_dup 0)))
10531
   (set (match_dup 1)
10532
        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10533
                         (match_operand:SI 3 "register_operand" "r")
10534
                         (match_dup 1)))]
10535
  "TARGET_CMOVE"
10536
  "")
10537
 
10538
(define_expand "x86_shift_adj_2"
10539
  [(use (match_operand:SI 0 "register_operand" ""))
10540
   (use (match_operand:SI 1 "register_operand" ""))
10541
   (use (match_operand:QI 2 "register_operand" ""))]
10542
  ""
10543
{
10544
  rtx label = gen_label_rtx ();
10545
  rtx tmp;
10546
 
10547
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10548
 
10549
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10550
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10551
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10552
                              gen_rtx_LABEL_REF (VOIDmode, label),
10553
                              pc_rtx);
10554
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10555
  JUMP_LABEL (tmp) = label;
10556
 
10557
  emit_move_insn (operands[0], operands[1]);
10558
  ix86_expand_clear (operands[1]);
10559
 
10560
  emit_label (label);
10561
  LABEL_NUSES (label) = 1;
10562
 
10563
  DONE;
10564
})
10565
 
10566
(define_expand "ashlsi3"
10567
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10568
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10569
                   (match_operand:QI 2 "nonmemory_operand" "")))
10570
   (clobber (reg:CC FLAGS_REG))]
10571
  ""
10572
  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10573
 
10574
(define_insn "*ashlsi3_1"
10575
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10576
        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10577
                   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10578
   (clobber (reg:CC FLAGS_REG))]
10579
  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10580
{
10581
  switch (get_attr_type (insn))
10582
    {
10583
    case TYPE_ALU:
10584
      gcc_assert (operands[2] == const1_rtx);
10585
      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10586
      return "add{l}\t{%0, %0|%0, %0}";
10587
 
10588
    case TYPE_LEA:
10589
      return "#";
10590
 
10591
    default:
10592
      if (REG_P (operands[2]))
10593
        return "sal{l}\t{%b2, %0|%0, %b2}";
10594
      else if (operands[2] == const1_rtx
10595
               && (TARGET_SHIFT1 || optimize_size))
10596
        return "sal{l}\t%0";
10597
      else
10598
        return "sal{l}\t{%2, %0|%0, %2}";
10599
    }
10600
}
10601
  [(set (attr "type")
10602
     (cond [(eq_attr "alternative" "1")
10603
              (const_string "lea")
10604
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10605
                          (const_int 0))
10606
                      (match_operand 0 "register_operand" ""))
10607
                 (match_operand 2 "const1_operand" ""))
10608
              (const_string "alu")
10609
           ]
10610
           (const_string "ishift")))
10611
   (set_attr "mode" "SI")])
10612
 
10613
;; Convert lea to the lea pattern to avoid flags dependency.
10614
(define_split
10615
  [(set (match_operand 0 "register_operand" "")
10616
        (ashift (match_operand 1 "index_register_operand" "")
10617
                (match_operand:QI 2 "const_int_operand" "")))
10618
   (clobber (reg:CC FLAGS_REG))]
10619
  "reload_completed
10620
   && true_regnum (operands[0]) != true_regnum (operands[1])
10621
   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10622
  [(const_int 0)]
10623
{
10624
  rtx pat;
10625
  enum machine_mode mode = GET_MODE (operands[0]);
10626
 
10627
  if (GET_MODE_SIZE (mode) < 4)
10628
    operands[0] = gen_lowpart (SImode, operands[0]);
10629
  if (mode != Pmode)
10630
    operands[1] = gen_lowpart (Pmode, operands[1]);
10631
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10632
 
10633
  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10634
  if (Pmode != SImode)
10635
    pat = gen_rtx_SUBREG (SImode, pat, 0);
10636
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10637
  DONE;
10638
})
10639
 
10640
;; Rare case of shifting RSP is handled by generating move and shift
10641
(define_split
10642
  [(set (match_operand 0 "register_operand" "")
10643
        (ashift (match_operand 1 "register_operand" "")
10644
                (match_operand:QI 2 "const_int_operand" "")))
10645
   (clobber (reg:CC FLAGS_REG))]
10646
  "reload_completed
10647
   && true_regnum (operands[0]) != true_regnum (operands[1])"
10648
  [(const_int 0)]
10649
{
10650
  rtx pat, clob;
10651
  emit_move_insn (operands[0], operands[1]);
10652
  pat = gen_rtx_SET (VOIDmode, operands[0],
10653
                     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10654
                                     operands[0], operands[2]));
10655
  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10656
  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10657
  DONE;
10658
})
10659
 
10660
(define_insn "*ashlsi3_1_zext"
10661
  [(set (match_operand:DI 0 "register_operand" "=r,r")
10662
        (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10663
                        (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10664
   (clobber (reg:CC FLAGS_REG))]
10665
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10666
{
10667
  switch (get_attr_type (insn))
10668
    {
10669
    case TYPE_ALU:
10670
      gcc_assert (operands[2] == const1_rtx);
10671
      return "add{l}\t{%k0, %k0|%k0, %k0}";
10672
 
10673
    case TYPE_LEA:
10674
      return "#";
10675
 
10676
    default:
10677
      if (REG_P (operands[2]))
10678
        return "sal{l}\t{%b2, %k0|%k0, %b2}";
10679
      else if (operands[2] == const1_rtx
10680
               && (TARGET_SHIFT1 || optimize_size))
10681
        return "sal{l}\t%k0";
10682
      else
10683
        return "sal{l}\t{%2, %k0|%k0, %2}";
10684
    }
10685
}
10686
  [(set (attr "type")
10687
     (cond [(eq_attr "alternative" "1")
10688
              (const_string "lea")
10689
            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10690
                     (const_int 0))
10691
                 (match_operand 2 "const1_operand" ""))
10692
              (const_string "alu")
10693
           ]
10694
           (const_string "ishift")))
10695
   (set_attr "mode" "SI")])
10696
 
10697
;; Convert lea to the lea pattern to avoid flags dependency.
10698
(define_split
10699
  [(set (match_operand:DI 0 "register_operand" "")
10700
        (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10701
                                (match_operand:QI 2 "const_int_operand" ""))))
10702
   (clobber (reg:CC FLAGS_REG))]
10703
  "TARGET_64BIT && reload_completed
10704
   && true_regnum (operands[0]) != true_regnum (operands[1])"
10705
  [(set (match_dup 0) (zero_extend:DI
10706
                        (subreg:SI (mult:SI (match_dup 1)
10707
                                            (match_dup 2)) 0)))]
10708
{
10709
  operands[1] = gen_lowpart (Pmode, operands[1]);
10710
  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10711
})
10712
 
10713
;; This pattern can't accept a variable shift count, since shifts by
10714
;; zero don't affect the flags.  We assume that shifts by constant
10715
;; zero are optimized away.
10716
(define_insn "*ashlsi3_cmp"
10717
  [(set (reg FLAGS_REG)
10718
        (compare
10719
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10720
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10721
          (const_int 0)))
10722
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10723
        (ashift:SI (match_dup 1) (match_dup 2)))]
10724
  "ix86_match_ccmode (insn, CCGOCmode)
10725
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10726
   && (optimize_size
10727
       || !TARGET_PARTIAL_FLAG_REG_STALL
10728
       || (operands[2] == const1_rtx
10729
           && (TARGET_SHIFT1
10730
               || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10731
{
10732
  switch (get_attr_type (insn))
10733
    {
10734
    case TYPE_ALU:
10735
      gcc_assert (operands[2] == const1_rtx);
10736
      return "add{l}\t{%0, %0|%0, %0}";
10737
 
10738
    default:
10739
      if (REG_P (operands[2]))
10740
        return "sal{l}\t{%b2, %0|%0, %b2}";
10741
      else if (operands[2] == const1_rtx
10742
               && (TARGET_SHIFT1 || optimize_size))
10743
        return "sal{l}\t%0";
10744
      else
10745
        return "sal{l}\t{%2, %0|%0, %2}";
10746
    }
10747
}
10748
  [(set (attr "type")
10749
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10750
                          (const_int 0))
10751
                      (match_operand 0 "register_operand" ""))
10752
                 (match_operand 2 "const1_operand" ""))
10753
              (const_string "alu")
10754
           ]
10755
           (const_string "ishift")))
10756
   (set_attr "mode" "SI")])
10757
 
10758
(define_insn "*ashlsi3_cconly"
10759
  [(set (reg FLAGS_REG)
10760
        (compare
10761
          (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10762
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10763
          (const_int 0)))
10764
   (clobber (match_scratch:SI 0 "=r"))]
10765
  "ix86_match_ccmode (insn, CCGOCmode)
10766
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10767
   && (optimize_size
10768
       || !TARGET_PARTIAL_FLAG_REG_STALL
10769
       || (operands[2] == const1_rtx
10770
           && (TARGET_SHIFT1
10771
               || TARGET_DOUBLE_WITH_ADD)))"
10772
{
10773
  switch (get_attr_type (insn))
10774
    {
10775
    case TYPE_ALU:
10776
      gcc_assert (operands[2] == const1_rtx);
10777
      return "add{l}\t{%0, %0|%0, %0}";
10778
 
10779
    default:
10780
      if (REG_P (operands[2]))
10781
        return "sal{l}\t{%b2, %0|%0, %b2}";
10782
      else if (operands[2] == const1_rtx
10783
               && (TARGET_SHIFT1 || optimize_size))
10784
        return "sal{l}\t%0";
10785
      else
10786
        return "sal{l}\t{%2, %0|%0, %2}";
10787
    }
10788
}
10789
  [(set (attr "type")
10790
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10791
                          (const_int 0))
10792
                      (match_operand 0 "register_operand" ""))
10793
                 (match_operand 2 "const1_operand" ""))
10794
              (const_string "alu")
10795
           ]
10796
           (const_string "ishift")))
10797
   (set_attr "mode" "SI")])
10798
 
10799
(define_insn "*ashlsi3_cmp_zext"
10800
  [(set (reg FLAGS_REG)
10801
        (compare
10802
          (ashift:SI (match_operand:SI 1 "register_operand" "0")
10803
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10804
          (const_int 0)))
10805
   (set (match_operand:DI 0 "register_operand" "=r")
10806
        (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10807
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10808
   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10809
   && (optimize_size
10810
       || !TARGET_PARTIAL_FLAG_REG_STALL
10811
       || (operands[2] == const1_rtx
10812
           && (TARGET_SHIFT1
10813
               || TARGET_DOUBLE_WITH_ADD)))"
10814
{
10815
  switch (get_attr_type (insn))
10816
    {
10817
    case TYPE_ALU:
10818
      gcc_assert (operands[2] == const1_rtx);
10819
      return "add{l}\t{%k0, %k0|%k0, %k0}";
10820
 
10821
    default:
10822
      if (REG_P (operands[2]))
10823
        return "sal{l}\t{%b2, %k0|%k0, %b2}";
10824
      else if (operands[2] == const1_rtx
10825
               && (TARGET_SHIFT1 || optimize_size))
10826
        return "sal{l}\t%k0";
10827
      else
10828
        return "sal{l}\t{%2, %k0|%k0, %2}";
10829
    }
10830
}
10831
  [(set (attr "type")
10832
     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10833
                     (const_int 0))
10834
                 (match_operand 2 "const1_operand" ""))
10835
              (const_string "alu")
10836
           ]
10837
           (const_string "ishift")))
10838
   (set_attr "mode" "SI")])
10839
 
10840
(define_expand "ashlhi3"
10841
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10842
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10843
                   (match_operand:QI 2 "nonmemory_operand" "")))
10844
   (clobber (reg:CC FLAGS_REG))]
10845
  "TARGET_HIMODE_MATH"
10846
  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10847
 
10848
(define_insn "*ashlhi3_1_lea"
10849
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10850
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10851
                   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10852
   (clobber (reg:CC FLAGS_REG))]
10853
  "!TARGET_PARTIAL_REG_STALL
10854
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10855
{
10856
  switch (get_attr_type (insn))
10857
    {
10858
    case TYPE_LEA:
10859
      return "#";
10860
    case TYPE_ALU:
10861
      gcc_assert (operands[2] == const1_rtx);
10862
      return "add{w}\t{%0, %0|%0, %0}";
10863
 
10864
    default:
10865
      if (REG_P (operands[2]))
10866
        return "sal{w}\t{%b2, %0|%0, %b2}";
10867
      else if (operands[2] == const1_rtx
10868
               && (TARGET_SHIFT1 || optimize_size))
10869
        return "sal{w}\t%0";
10870
      else
10871
        return "sal{w}\t{%2, %0|%0, %2}";
10872
    }
10873
}
10874
  [(set (attr "type")
10875
     (cond [(eq_attr "alternative" "1")
10876
              (const_string "lea")
10877
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10878
                          (const_int 0))
10879
                      (match_operand 0 "register_operand" ""))
10880
                 (match_operand 2 "const1_operand" ""))
10881
              (const_string "alu")
10882
           ]
10883
           (const_string "ishift")))
10884
   (set_attr "mode" "HI,SI")])
10885
 
10886
(define_insn "*ashlhi3_1"
10887
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10888
        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10889
                   (match_operand:QI 2 "nonmemory_operand" "cI")))
10890
   (clobber (reg:CC FLAGS_REG))]
10891
  "TARGET_PARTIAL_REG_STALL
10892
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10893
{
10894
  switch (get_attr_type (insn))
10895
    {
10896
    case TYPE_ALU:
10897
      gcc_assert (operands[2] == const1_rtx);
10898
      return "add{w}\t{%0, %0|%0, %0}";
10899
 
10900
    default:
10901
      if (REG_P (operands[2]))
10902
        return "sal{w}\t{%b2, %0|%0, %b2}";
10903
      else if (operands[2] == const1_rtx
10904
               && (TARGET_SHIFT1 || optimize_size))
10905
        return "sal{w}\t%0";
10906
      else
10907
        return "sal{w}\t{%2, %0|%0, %2}";
10908
    }
10909
}
10910
  [(set (attr "type")
10911
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10912
                          (const_int 0))
10913
                      (match_operand 0 "register_operand" ""))
10914
                 (match_operand 2 "const1_operand" ""))
10915
              (const_string "alu")
10916
           ]
10917
           (const_string "ishift")))
10918
   (set_attr "mode" "HI")])
10919
 
10920
;; This pattern can't accept a variable shift count, since shifts by
10921
;; zero don't affect the flags.  We assume that shifts by constant
10922
;; zero are optimized away.
10923
(define_insn "*ashlhi3_cmp"
10924
  [(set (reg FLAGS_REG)
10925
        (compare
10926
          (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10927
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10928
          (const_int 0)))
10929
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10930
        (ashift:HI (match_dup 1) (match_dup 2)))]
10931
  "ix86_match_ccmode (insn, CCGOCmode)
10932
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10933
   && (optimize_size
10934
       || !TARGET_PARTIAL_FLAG_REG_STALL
10935
       || (operands[2] == const1_rtx
10936
           && (TARGET_SHIFT1
10937
               || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10938
{
10939
  switch (get_attr_type (insn))
10940
    {
10941
    case TYPE_ALU:
10942
      gcc_assert (operands[2] == const1_rtx);
10943
      return "add{w}\t{%0, %0|%0, %0}";
10944
 
10945
    default:
10946
      if (REG_P (operands[2]))
10947
        return "sal{w}\t{%b2, %0|%0, %b2}";
10948
      else if (operands[2] == const1_rtx
10949
               && (TARGET_SHIFT1 || optimize_size))
10950
        return "sal{w}\t%0";
10951
      else
10952
        return "sal{w}\t{%2, %0|%0, %2}";
10953
    }
10954
}
10955
  [(set (attr "type")
10956
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10957
                          (const_int 0))
10958
                      (match_operand 0 "register_operand" ""))
10959
                 (match_operand 2 "const1_operand" ""))
10960
              (const_string "alu")
10961
           ]
10962
           (const_string "ishift")))
10963
   (set_attr "mode" "HI")])
10964
 
10965
(define_insn "*ashlhi3_cconly"
10966
  [(set (reg FLAGS_REG)
10967
        (compare
10968
          (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10969
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10970
          (const_int 0)))
10971
   (clobber (match_scratch:HI 0 "=r"))]
10972
  "ix86_match_ccmode (insn, CCGOCmode)
10973
   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10974
   && (optimize_size
10975
       || !TARGET_PARTIAL_FLAG_REG_STALL
10976
       || (operands[2] == const1_rtx
10977
           && (TARGET_SHIFT1
10978
               || TARGET_DOUBLE_WITH_ADD)))"
10979
{
10980
  switch (get_attr_type (insn))
10981
    {
10982
    case TYPE_ALU:
10983
      gcc_assert (operands[2] == const1_rtx);
10984
      return "add{w}\t{%0, %0|%0, %0}";
10985
 
10986
    default:
10987
      if (REG_P (operands[2]))
10988
        return "sal{w}\t{%b2, %0|%0, %b2}";
10989
      else if (operands[2] == const1_rtx
10990
               && (TARGET_SHIFT1 || optimize_size))
10991
        return "sal{w}\t%0";
10992
      else
10993
        return "sal{w}\t{%2, %0|%0, %2}";
10994
    }
10995
}
10996
  [(set (attr "type")
10997
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998
                          (const_int 0))
10999
                      (match_operand 0 "register_operand" ""))
11000
                 (match_operand 2 "const1_operand" ""))
11001
              (const_string "alu")
11002
           ]
11003
           (const_string "ishift")))
11004
   (set_attr "mode" "HI")])
11005
 
11006
(define_expand "ashlqi3"
11007
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11008
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11009
                   (match_operand:QI 2 "nonmemory_operand" "")))
11010
   (clobber (reg:CC FLAGS_REG))]
11011
  "TARGET_QIMODE_MATH"
11012
  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11013
 
11014
;; %%% Potential partial reg stall on alternative 2.  What to do?
11015
 
11016
(define_insn "*ashlqi3_1_lea"
11017
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11018
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11019
                   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11020
   (clobber (reg:CC FLAGS_REG))]
11021
  "!TARGET_PARTIAL_REG_STALL
11022
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11023
{
11024
  switch (get_attr_type (insn))
11025
    {
11026
    case TYPE_LEA:
11027
      return "#";
11028
    case TYPE_ALU:
11029
      gcc_assert (operands[2] == const1_rtx);
11030
      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11031
        return "add{l}\t{%k0, %k0|%k0, %k0}";
11032
      else
11033
        return "add{b}\t{%0, %0|%0, %0}";
11034
 
11035
    default:
11036
      if (REG_P (operands[2]))
11037
        {
11038
          if (get_attr_mode (insn) == MODE_SI)
11039
            return "sal{l}\t{%b2, %k0|%k0, %b2}";
11040
          else
11041
            return "sal{b}\t{%b2, %0|%0, %b2}";
11042
        }
11043
      else if (operands[2] == const1_rtx
11044
               && (TARGET_SHIFT1 || optimize_size))
11045
        {
11046
          if (get_attr_mode (insn) == MODE_SI)
11047
            return "sal{l}\t%0";
11048
          else
11049
            return "sal{b}\t%0";
11050
        }
11051
      else
11052
        {
11053
          if (get_attr_mode (insn) == MODE_SI)
11054
            return "sal{l}\t{%2, %k0|%k0, %2}";
11055
          else
11056
            return "sal{b}\t{%2, %0|%0, %2}";
11057
        }
11058
    }
11059
}
11060
  [(set (attr "type")
11061
     (cond [(eq_attr "alternative" "2")
11062
              (const_string "lea")
11063
            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11064
                          (const_int 0))
11065
                      (match_operand 0 "register_operand" ""))
11066
                 (match_operand 2 "const1_operand" ""))
11067
              (const_string "alu")
11068
           ]
11069
           (const_string "ishift")))
11070
   (set_attr "mode" "QI,SI,SI")])
11071
 
11072
(define_insn "*ashlqi3_1"
11073
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11074
        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11075
                   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11076
   (clobber (reg:CC FLAGS_REG))]
11077
  "TARGET_PARTIAL_REG_STALL
11078
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11079
{
11080
  switch (get_attr_type (insn))
11081
    {
11082
    case TYPE_ALU:
11083
      gcc_assert (operands[2] == const1_rtx);
11084
      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11085
        return "add{l}\t{%k0, %k0|%k0, %k0}";
11086
      else
11087
        return "add{b}\t{%0, %0|%0, %0}";
11088
 
11089
    default:
11090
      if (REG_P (operands[2]))
11091
        {
11092
          if (get_attr_mode (insn) == MODE_SI)
11093
            return "sal{l}\t{%b2, %k0|%k0, %b2}";
11094
          else
11095
            return "sal{b}\t{%b2, %0|%0, %b2}";
11096
        }
11097
      else if (operands[2] == const1_rtx
11098
               && (TARGET_SHIFT1 || optimize_size))
11099
        {
11100
          if (get_attr_mode (insn) == MODE_SI)
11101
            return "sal{l}\t%0";
11102
          else
11103
            return "sal{b}\t%0";
11104
        }
11105
      else
11106
        {
11107
          if (get_attr_mode (insn) == MODE_SI)
11108
            return "sal{l}\t{%2, %k0|%k0, %2}";
11109
          else
11110
            return "sal{b}\t{%2, %0|%0, %2}";
11111
        }
11112
    }
11113
}
11114
  [(set (attr "type")
11115
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11116
                          (const_int 0))
11117
                      (match_operand 0 "register_operand" ""))
11118
                 (match_operand 2 "const1_operand" ""))
11119
              (const_string "alu")
11120
           ]
11121
           (const_string "ishift")))
11122
   (set_attr "mode" "QI,SI")])
11123
 
11124
;; This pattern can't accept a variable shift count, since shifts by
11125
;; zero don't affect the flags.  We assume that shifts by constant
11126
;; zero are optimized away.
11127
(define_insn "*ashlqi3_cmp"
11128
  [(set (reg FLAGS_REG)
11129
        (compare
11130
          (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11131
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11132
          (const_int 0)))
11133
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11134
        (ashift:QI (match_dup 1) (match_dup 2)))]
11135
  "ix86_match_ccmode (insn, CCGOCmode)
11136
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11137
   && (optimize_size
11138
       || !TARGET_PARTIAL_FLAG_REG_STALL
11139
       || (operands[2] == const1_rtx
11140
           && (TARGET_SHIFT1
11141
               || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11142
{
11143
  switch (get_attr_type (insn))
11144
    {
11145
    case TYPE_ALU:
11146
      gcc_assert (operands[2] == const1_rtx);
11147
      return "add{b}\t{%0, %0|%0, %0}";
11148
 
11149
    default:
11150
      if (REG_P (operands[2]))
11151
        return "sal{b}\t{%b2, %0|%0, %b2}";
11152
      else if (operands[2] == const1_rtx
11153
               && (TARGET_SHIFT1 || optimize_size))
11154
        return "sal{b}\t%0";
11155
      else
11156
        return "sal{b}\t{%2, %0|%0, %2}";
11157
    }
11158
}
11159
  [(set (attr "type")
11160
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11161
                          (const_int 0))
11162
                      (match_operand 0 "register_operand" ""))
11163
                 (match_operand 2 "const1_operand" ""))
11164
              (const_string "alu")
11165
           ]
11166
           (const_string "ishift")))
11167
   (set_attr "mode" "QI")])
11168
 
11169
(define_insn "*ashlqi3_cconly"
11170
  [(set (reg FLAGS_REG)
11171
        (compare
11172
          (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11173
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11174
          (const_int 0)))
11175
   (clobber (match_scratch:QI 0 "=q"))]
11176
  "ix86_match_ccmode (insn, CCGOCmode)
11177
   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11178
   && (optimize_size
11179
       || !TARGET_PARTIAL_FLAG_REG_STALL
11180
       || (operands[2] == const1_rtx
11181
           && (TARGET_SHIFT1
11182
               || TARGET_DOUBLE_WITH_ADD)))"
11183
{
11184
  switch (get_attr_type (insn))
11185
    {
11186
    case TYPE_ALU:
11187
      gcc_assert (operands[2] == const1_rtx);
11188
      return "add{b}\t{%0, %0|%0, %0}";
11189
 
11190
    default:
11191
      if (REG_P (operands[2]))
11192
        return "sal{b}\t{%b2, %0|%0, %b2}";
11193
      else if (operands[2] == const1_rtx
11194
               && (TARGET_SHIFT1 || optimize_size))
11195
        return "sal{b}\t%0";
11196
      else
11197
        return "sal{b}\t{%2, %0|%0, %2}";
11198
    }
11199
}
11200
  [(set (attr "type")
11201
     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11202
                          (const_int 0))
11203
                      (match_operand 0 "register_operand" ""))
11204
                 (match_operand 2 "const1_operand" ""))
11205
              (const_string "alu")
11206
           ]
11207
           (const_string "ishift")))
11208
   (set_attr "mode" "QI")])
11209
 
11210
;; See comment above `ashldi3' about how this works.
11211
 
11212
(define_expand "ashrti3"
11213
  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11214
                   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11215
                                (match_operand:QI 2 "nonmemory_operand" "")))
11216
              (clobber (reg:CC FLAGS_REG))])]
11217
  "TARGET_64BIT"
11218
{
11219
  if (! immediate_operand (operands[2], QImode))
11220
    {
11221
      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11222
      DONE;
11223
    }
11224
  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11225
  DONE;
11226
})
11227
 
11228
(define_insn "ashrti3_1"
11229
  [(set (match_operand:TI 0 "register_operand" "=r")
11230
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11231
                     (match_operand:QI 2 "register_operand" "c")))
11232
   (clobber (match_scratch:DI 3 "=&r"))
11233
   (clobber (reg:CC FLAGS_REG))]
11234
  "TARGET_64BIT"
11235
  "#"
11236
  [(set_attr "type" "multi")])
11237
 
11238
(define_insn "*ashrti3_2"
11239
  [(set (match_operand:TI 0 "register_operand" "=r")
11240
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11241
                     (match_operand:QI 2 "immediate_operand" "O")))
11242
   (clobber (reg:CC FLAGS_REG))]
11243
  "TARGET_64BIT"
11244
  "#"
11245
  [(set_attr "type" "multi")])
11246
 
11247
(define_split
11248
  [(set (match_operand:TI 0 "register_operand" "")
11249
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11250
                     (match_operand:QI 2 "register_operand" "")))
11251
   (clobber (match_scratch:DI 3 ""))
11252
   (clobber (reg:CC FLAGS_REG))]
11253
  "TARGET_64BIT && reload_completed"
11254
  [(const_int 0)]
11255
  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11256
 
11257
(define_split
11258
  [(set (match_operand:TI 0 "register_operand" "")
11259
        (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11260
                     (match_operand:QI 2 "immediate_operand" "")))
11261
   (clobber (reg:CC FLAGS_REG))]
11262
  "TARGET_64BIT && reload_completed"
11263
  [(const_int 0)]
11264
  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11265
 
11266
(define_insn "x86_64_shrd"
11267
  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11268
        (ior:DI (ashiftrt:DI (match_dup 0)
11269
                  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11270
                (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11271
                  (minus:QI (const_int 64) (match_dup 2)))))
11272
   (clobber (reg:CC FLAGS_REG))]
11273
  "TARGET_64BIT"
11274
  "@
11275
   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11276
   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11277
  [(set_attr "type" "ishift")
11278
   (set_attr "prefix_0f" "1")
11279
   (set_attr "mode" "DI")
11280
   (set_attr "athlon_decode" "vector")])
11281
 
11282
(define_expand "ashrdi3"
11283
  [(set (match_operand:DI 0 "shiftdi_operand" "")
11284
        (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11285
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11286
  ""
11287
  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11288
 
11289
(define_insn "*ashrdi3_63_rex64"
11290
  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11291
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11292
                     (match_operand:DI 2 "const_int_operand" "i,i")))
11293
   (clobber (reg:CC FLAGS_REG))]
11294
  "TARGET_64BIT && INTVAL (operands[2]) == 63
11295
   && (TARGET_USE_CLTD || optimize_size)
11296
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11297
  "@
11298
   {cqto|cqo}
11299
   sar{q}\t{%2, %0|%0, %2}"
11300
  [(set_attr "type" "imovx,ishift")
11301
   (set_attr "prefix_0f" "0,*")
11302
   (set_attr "length_immediate" "0,*")
11303
   (set_attr "modrm" "0,1")
11304
   (set_attr "mode" "DI")])
11305
 
11306
(define_insn "*ashrdi3_1_one_bit_rex64"
11307
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11308
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11309
                     (match_operand:QI 2 "const1_operand" "")))
11310
   (clobber (reg:CC FLAGS_REG))]
11311
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11312
   && (TARGET_SHIFT1 || optimize_size)"
11313
  "sar{q}\t%0"
11314
  [(set_attr "type" "ishift")
11315
   (set (attr "length")
11316
     (if_then_else (match_operand:DI 0 "register_operand" "")
11317
        (const_string "2")
11318
        (const_string "*")))])
11319
 
11320
(define_insn "*ashrdi3_1_rex64"
11321
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11322
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11323
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11324
   (clobber (reg:CC FLAGS_REG))]
11325
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11326
  "@
11327
   sar{q}\t{%2, %0|%0, %2}
11328
   sar{q}\t{%b2, %0|%0, %b2}"
11329
  [(set_attr "type" "ishift")
11330
   (set_attr "mode" "DI")])
11331
 
11332
;; This pattern can't accept a variable shift count, since shifts by
11333
;; zero don't affect the flags.  We assume that shifts by constant
11334
;; zero are optimized away.
11335
(define_insn "*ashrdi3_one_bit_cmp_rex64"
11336
  [(set (reg FLAGS_REG)
11337
        (compare
11338
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11339
                       (match_operand:QI 2 "const1_operand" ""))
11340
          (const_int 0)))
11341
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11342
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11343
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11344
   && (TARGET_SHIFT1 || optimize_size)
11345
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11346
  "sar{q}\t%0"
11347
  [(set_attr "type" "ishift")
11348
   (set (attr "length")
11349
     (if_then_else (match_operand:DI 0 "register_operand" "")
11350
        (const_string "2")
11351
        (const_string "*")))])
11352
 
11353
(define_insn "*ashrdi3_one_bit_cconly_rex64"
11354
  [(set (reg FLAGS_REG)
11355
        (compare
11356
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11357
                       (match_operand:QI 2 "const1_operand" ""))
11358
          (const_int 0)))
11359
   (clobber (match_scratch:DI 0 "=r"))]
11360
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11361
   && (TARGET_SHIFT1 || optimize_size)
11362
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11363
  "sar{q}\t%0"
11364
  [(set_attr "type" "ishift")
11365
   (set_attr "length" "2")])
11366
 
11367
;; This pattern can't accept a variable shift count, since shifts by
11368
;; zero don't affect the flags.  We assume that shifts by constant
11369
;; zero are optimized away.
11370
(define_insn "*ashrdi3_cmp_rex64"
11371
  [(set (reg FLAGS_REG)
11372
        (compare
11373
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11374
                       (match_operand:QI 2 "const_int_operand" "n"))
11375
          (const_int 0)))
11376
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11377
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11378
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11379
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11380
   && (optimize_size
11381
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11382
  "sar{q}\t{%2, %0|%0, %2}"
11383
  [(set_attr "type" "ishift")
11384
   (set_attr "mode" "DI")])
11385
 
11386
(define_insn "*ashrdi3_cconly_rex64"
11387
  [(set (reg FLAGS_REG)
11388
        (compare
11389
          (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390
                       (match_operand:QI 2 "const_int_operand" "n"))
11391
          (const_int 0)))
11392
   (clobber (match_scratch:DI 0 "=r"))]
11393
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11394
   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11395
   && (optimize_size
11396
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11397
  "sar{q}\t{%2, %0|%0, %2}"
11398
  [(set_attr "type" "ishift")
11399
   (set_attr "mode" "DI")])
11400
 
11401
(define_insn "*ashrdi3_1"
11402
  [(set (match_operand:DI 0 "register_operand" "=r")
11403
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11404
                     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11405
   (clobber (reg:CC FLAGS_REG))]
11406
  "!TARGET_64BIT"
11407
  "#"
11408
  [(set_attr "type" "multi")])
11409
 
11410
;; By default we don't ask for a scratch register, because when DImode
11411
;; values are manipulated, registers are already at a premium.  But if
11412
;; we have one handy, we won't turn it away.
11413
(define_peephole2
11414
  [(match_scratch:SI 3 "r")
11415
   (parallel [(set (match_operand:DI 0 "register_operand" "")
11416
                   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11417
                                (match_operand:QI 2 "nonmemory_operand" "")))
11418
              (clobber (reg:CC FLAGS_REG))])
11419
   (match_dup 3)]
11420
  "!TARGET_64BIT && TARGET_CMOVE"
11421
  [(const_int 0)]
11422
  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11423
 
11424
(define_split
11425
  [(set (match_operand:DI 0 "register_operand" "")
11426
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11427
                     (match_operand:QI 2 "nonmemory_operand" "")))
11428
   (clobber (reg:CC FLAGS_REG))]
11429
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11430
                     ? flow2_completed : reload_completed)"
11431
  [(const_int 0)]
11432
  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11433
 
11434
(define_insn "x86_shrd_1"
11435
  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11436
        (ior:SI (ashiftrt:SI (match_dup 0)
11437
                  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11438
                (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11439
                  (minus:QI (const_int 32) (match_dup 2)))))
11440
   (clobber (reg:CC FLAGS_REG))]
11441
  ""
11442
  "@
11443
   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11444
   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11445
  [(set_attr "type" "ishift")
11446
   (set_attr "prefix_0f" "1")
11447
   (set_attr "pent_pair" "np")
11448
   (set_attr "mode" "SI")])
11449
 
11450
(define_expand "x86_shift_adj_3"
11451
  [(use (match_operand:SI 0 "register_operand" ""))
11452
   (use (match_operand:SI 1 "register_operand" ""))
11453
   (use (match_operand:QI 2 "register_operand" ""))]
11454
  ""
11455
{
11456
  rtx label = gen_label_rtx ();
11457
  rtx tmp;
11458
 
11459
  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11460
 
11461
  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11462
  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11463
  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11464
                              gen_rtx_LABEL_REF (VOIDmode, label),
11465
                              pc_rtx);
11466
  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11467
  JUMP_LABEL (tmp) = label;
11468
 
11469
  emit_move_insn (operands[0], operands[1]);
11470
  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11471
 
11472
  emit_label (label);
11473
  LABEL_NUSES (label) = 1;
11474
 
11475
  DONE;
11476
})
11477
 
11478
(define_insn "ashrsi3_31"
11479
  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11480
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11481
                     (match_operand:SI 2 "const_int_operand" "i,i")))
11482
   (clobber (reg:CC FLAGS_REG))]
11483
  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11484
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11485
  "@
11486
   {cltd|cdq}
11487
   sar{l}\t{%2, %0|%0, %2}"
11488
  [(set_attr "type" "imovx,ishift")
11489
   (set_attr "prefix_0f" "0,*")
11490
   (set_attr "length_immediate" "0,*")
11491
   (set_attr "modrm" "0,1")
11492
   (set_attr "mode" "SI")])
11493
 
11494
(define_insn "*ashrsi3_31_zext"
11495
  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11496
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11497
                                     (match_operand:SI 2 "const_int_operand" "i,i"))))
11498
   (clobber (reg:CC FLAGS_REG))]
11499
  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11500
   && INTVAL (operands[2]) == 31
11501
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11502
  "@
11503
   {cltd|cdq}
11504
   sar{l}\t{%2, %k0|%k0, %2}"
11505
  [(set_attr "type" "imovx,ishift")
11506
   (set_attr "prefix_0f" "0,*")
11507
   (set_attr "length_immediate" "0,*")
11508
   (set_attr "modrm" "0,1")
11509
   (set_attr "mode" "SI")])
11510
 
11511
(define_expand "ashrsi3"
11512
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11513
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11514
                     (match_operand:QI 2 "nonmemory_operand" "")))
11515
   (clobber (reg:CC FLAGS_REG))]
11516
  ""
11517
  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11518
 
11519
(define_insn "*ashrsi3_1_one_bit"
11520
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11521
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11522
                     (match_operand:QI 2 "const1_operand" "")))
11523
   (clobber (reg:CC FLAGS_REG))]
11524
  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11525
   && (TARGET_SHIFT1 || optimize_size)"
11526
  "sar{l}\t%0"
11527
  [(set_attr "type" "ishift")
11528
   (set (attr "length")
11529
     (if_then_else (match_operand:SI 0 "register_operand" "")
11530
        (const_string "2")
11531
        (const_string "*")))])
11532
 
11533
(define_insn "*ashrsi3_1_one_bit_zext"
11534
  [(set (match_operand:DI 0 "register_operand" "=r")
11535
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11536
                                     (match_operand:QI 2 "const1_operand" ""))))
11537
   (clobber (reg:CC FLAGS_REG))]
11538
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11539
   && (TARGET_SHIFT1 || optimize_size)"
11540
  "sar{l}\t%k0"
11541
  [(set_attr "type" "ishift")
11542
   (set_attr "length" "2")])
11543
 
11544
(define_insn "*ashrsi3_1"
11545
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11546
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11547
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11548
   (clobber (reg:CC FLAGS_REG))]
11549
  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11550
  "@
11551
   sar{l}\t{%2, %0|%0, %2}
11552
   sar{l}\t{%b2, %0|%0, %b2}"
11553
  [(set_attr "type" "ishift")
11554
   (set_attr "mode" "SI")])
11555
 
11556
(define_insn "*ashrsi3_1_zext"
11557
  [(set (match_operand:DI 0 "register_operand" "=r,r")
11558
        (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11559
                                     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11560
   (clobber (reg:CC FLAGS_REG))]
11561
  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11562
  "@
11563
   sar{l}\t{%2, %k0|%k0, %2}
11564
   sar{l}\t{%b2, %k0|%k0, %b2}"
11565
  [(set_attr "type" "ishift")
11566
   (set_attr "mode" "SI")])
11567
 
11568
;; This pattern can't accept a variable shift count, since shifts by
11569
;; zero don't affect the flags.  We assume that shifts by constant
11570
;; zero are optimized away.
11571
(define_insn "*ashrsi3_one_bit_cmp"
11572
  [(set (reg FLAGS_REG)
11573
        (compare
11574
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11575
                       (match_operand:QI 2 "const1_operand" ""))
11576
          (const_int 0)))
11577
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11578
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11579
  "ix86_match_ccmode (insn, CCGOCmode)
11580
   && (TARGET_SHIFT1 || optimize_size)
11581
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11582
  "sar{l}\t%0"
11583
  [(set_attr "type" "ishift")
11584
   (set (attr "length")
11585
     (if_then_else (match_operand:SI 0 "register_operand" "")
11586
        (const_string "2")
11587
        (const_string "*")))])
11588
 
11589
(define_insn "*ashrsi3_one_bit_cconly"
11590
  [(set (reg FLAGS_REG)
11591
        (compare
11592
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11593
                       (match_operand:QI 2 "const1_operand" ""))
11594
          (const_int 0)))
11595
   (clobber (match_scratch:SI 0 "=r"))]
11596
  "ix86_match_ccmode (insn, CCGOCmode)
11597
   && (TARGET_SHIFT1 || optimize_size)
11598
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11599
  "sar{l}\t%0"
11600
  [(set_attr "type" "ishift")
11601
   (set_attr "length" "2")])
11602
 
11603
(define_insn "*ashrsi3_one_bit_cmp_zext"
11604
  [(set (reg FLAGS_REG)
11605
        (compare
11606
          (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607
                       (match_operand:QI 2 "const1_operand" ""))
11608
          (const_int 0)))
11609
   (set (match_operand:DI 0 "register_operand" "=r")
11610
        (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11611
  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11612
   && (TARGET_SHIFT1 || optimize_size)
11613
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11614
  "sar{l}\t%k0"
11615
  [(set_attr "type" "ishift")
11616
   (set_attr "length" "2")])
11617
 
11618
;; This pattern can't accept a variable shift count, since shifts by
11619
;; zero don't affect the flags.  We assume that shifts by constant
11620
;; zero are optimized away.
11621
(define_insn "*ashrsi3_cmp"
11622
  [(set (reg FLAGS_REG)
11623
        (compare
11624
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11626
          (const_int 0)))
11627
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11628
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11629
  "ix86_match_ccmode (insn, CCGOCmode)
11630
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11631
   && (optimize_size
11632
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11633
  "sar{l}\t{%2, %0|%0, %2}"
11634
  [(set_attr "type" "ishift")
11635
   (set_attr "mode" "SI")])
11636
 
11637
(define_insn "*ashrsi3_cconly"
11638
  [(set (reg FLAGS_REG)
11639
        (compare
11640
          (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11641
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642
          (const_int 0)))
11643
   (clobber (match_scratch:SI 0 "=r"))]
11644
  "ix86_match_ccmode (insn, CCGOCmode)
11645
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11646
   && (optimize_size
11647
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11648
  "sar{l}\t{%2, %0|%0, %2}"
11649
  [(set_attr "type" "ishift")
11650
   (set_attr "mode" "SI")])
11651
 
11652
(define_insn "*ashrsi3_cmp_zext"
11653
  [(set (reg FLAGS_REG)
11654
        (compare
11655
          (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11656
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11657
          (const_int 0)))
11658
   (set (match_operand:DI 0 "register_operand" "=r")
11659
        (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11660
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11661
   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11662
   && (optimize_size
11663
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11664
  "sar{l}\t{%2, %k0|%k0, %2}"
11665
  [(set_attr "type" "ishift")
11666
   (set_attr "mode" "SI")])
11667
 
11668
(define_expand "ashrhi3"
11669
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11670
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11671
                     (match_operand:QI 2 "nonmemory_operand" "")))
11672
   (clobber (reg:CC FLAGS_REG))]
11673
  "TARGET_HIMODE_MATH"
11674
  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11675
 
11676
(define_insn "*ashrhi3_1_one_bit"
11677
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11678
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11679
                     (match_operand:QI 2 "const1_operand" "")))
11680
   (clobber (reg:CC FLAGS_REG))]
11681
  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11682
   && (TARGET_SHIFT1 || optimize_size)"
11683
  "sar{w}\t%0"
11684
  [(set_attr "type" "ishift")
11685
   (set (attr "length")
11686
     (if_then_else (match_operand 0 "register_operand" "")
11687
        (const_string "2")
11688
        (const_string "*")))])
11689
 
11690
(define_insn "*ashrhi3_1"
11691
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11692
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11693
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11694
   (clobber (reg:CC FLAGS_REG))]
11695
  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11696
  "@
11697
   sar{w}\t{%2, %0|%0, %2}
11698
   sar{w}\t{%b2, %0|%0, %b2}"
11699
  [(set_attr "type" "ishift")
11700
   (set_attr "mode" "HI")])
11701
 
11702
;; This pattern can't accept a variable shift count, since shifts by
11703
;; zero don't affect the flags.  We assume that shifts by constant
11704
;; zero are optimized away.
11705
(define_insn "*ashrhi3_one_bit_cmp"
11706
  [(set (reg FLAGS_REG)
11707
        (compare
11708
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11709
                       (match_operand:QI 2 "const1_operand" ""))
11710
          (const_int 0)))
11711
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11712
        (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11713
  "ix86_match_ccmode (insn, CCGOCmode)
11714
   && (TARGET_SHIFT1 || optimize_size)
11715
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11716
  "sar{w}\t%0"
11717
  [(set_attr "type" "ishift")
11718
   (set (attr "length")
11719
     (if_then_else (match_operand 0 "register_operand" "")
11720
        (const_string "2")
11721
        (const_string "*")))])
11722
 
11723
(define_insn "*ashrhi3_one_bit_cconly"
11724
  [(set (reg FLAGS_REG)
11725
        (compare
11726
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11727
                       (match_operand:QI 2 "const1_operand" ""))
11728
          (const_int 0)))
11729
   (clobber (match_scratch:HI 0 "=r"))]
11730
  "ix86_match_ccmode (insn, CCGOCmode)
11731
   && (TARGET_SHIFT1 || optimize_size)
11732
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11733
  "sar{w}\t%0"
11734
  [(set_attr "type" "ishift")
11735
   (set_attr "length" "2")])
11736
 
11737
;; This pattern can't accept a variable shift count, since shifts by
11738
;; zero don't affect the flags.  We assume that shifts by constant
11739
;; zero are optimized away.
11740
(define_insn "*ashrhi3_cmp"
11741
  [(set (reg FLAGS_REG)
11742
        (compare
11743
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11744
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11745
          (const_int 0)))
11746
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11747
        (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11748
  "ix86_match_ccmode (insn, CCGOCmode)
11749
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11750
   && (optimize_size
11751
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11752
  "sar{w}\t{%2, %0|%0, %2}"
11753
  [(set_attr "type" "ishift")
11754
   (set_attr "mode" "HI")])
11755
 
11756
(define_insn "*ashrhi3_cconly"
11757
  [(set (reg FLAGS_REG)
11758
        (compare
11759
          (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11760
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761
          (const_int 0)))
11762
   (clobber (match_scratch:HI 0 "=r"))]
11763
  "ix86_match_ccmode (insn, CCGOCmode)
11764
   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11765
   && (optimize_size
11766
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767
  "sar{w}\t{%2, %0|%0, %2}"
11768
  [(set_attr "type" "ishift")
11769
   (set_attr "mode" "HI")])
11770
 
11771
(define_expand "ashrqi3"
11772
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11773
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11774
                     (match_operand:QI 2 "nonmemory_operand" "")))
11775
   (clobber (reg:CC FLAGS_REG))]
11776
  "TARGET_QIMODE_MATH"
11777
  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11778
 
11779
(define_insn "*ashrqi3_1_one_bit"
11780
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11781
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11782
                     (match_operand:QI 2 "const1_operand" "")))
11783
   (clobber (reg:CC FLAGS_REG))]
11784
  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11785
   && (TARGET_SHIFT1 || optimize_size)"
11786
  "sar{b}\t%0"
11787
  [(set_attr "type" "ishift")
11788
   (set (attr "length")
11789
     (if_then_else (match_operand 0 "register_operand" "")
11790
        (const_string "2")
11791
        (const_string "*")))])
11792
 
11793
(define_insn "*ashrqi3_1_one_bit_slp"
11794
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11795
        (ashiftrt:QI (match_dup 0)
11796
                     (match_operand:QI 1 "const1_operand" "")))
11797
   (clobber (reg:CC FLAGS_REG))]
11798
  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11799
   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11800
   && (TARGET_SHIFT1 || optimize_size)"
11801
  "sar{b}\t%0"
11802
  [(set_attr "type" "ishift1")
11803
   (set (attr "length")
11804
     (if_then_else (match_operand 0 "register_operand" "")
11805
        (const_string "2")
11806
        (const_string "*")))])
11807
 
11808
(define_insn "*ashrqi3_1"
11809
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11810
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11811
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11812
   (clobber (reg:CC FLAGS_REG))]
11813
  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11814
  "@
11815
   sar{b}\t{%2, %0|%0, %2}
11816
   sar{b}\t{%b2, %0|%0, %b2}"
11817
  [(set_attr "type" "ishift")
11818
   (set_attr "mode" "QI")])
11819
 
11820
(define_insn "*ashrqi3_1_slp"
11821
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11822
        (ashiftrt:QI (match_dup 0)
11823
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11824
   (clobber (reg:CC FLAGS_REG))]
11825
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11826
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11827
  "@
11828
   sar{b}\t{%1, %0|%0, %1}
11829
   sar{b}\t{%b1, %0|%0, %b1}"
11830
  [(set_attr "type" "ishift1")
11831
   (set_attr "mode" "QI")])
11832
 
11833
;; This pattern can't accept a variable shift count, since shifts by
11834
;; zero don't affect the flags.  We assume that shifts by constant
11835
;; zero are optimized away.
11836
(define_insn "*ashrqi3_one_bit_cmp"
11837
  [(set (reg FLAGS_REG)
11838
        (compare
11839
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11840
                       (match_operand:QI 2 "const1_operand" "I"))
11841
          (const_int 0)))
11842
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11843
        (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11844
  "ix86_match_ccmode (insn, CCGOCmode)
11845
   && (TARGET_SHIFT1 || optimize_size)
11846
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11847
  "sar{b}\t%0"
11848
  [(set_attr "type" "ishift")
11849
   (set (attr "length")
11850
     (if_then_else (match_operand 0 "register_operand" "")
11851
        (const_string "2")
11852
        (const_string "*")))])
11853
 
11854
(define_insn "*ashrqi3_one_bit_cconly"
11855
  [(set (reg FLAGS_REG)
11856
        (compare
11857
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11858
                       (match_operand:QI 2 "const1_operand" "I"))
11859
          (const_int 0)))
11860
   (clobber (match_scratch:QI 0 "=q"))]
11861
  "ix86_match_ccmode (insn, CCGOCmode)
11862
   && (TARGET_SHIFT1 || optimize_size)
11863
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11864
  "sar{b}\t%0"
11865
  [(set_attr "type" "ishift")
11866
   (set_attr "length" "2")])
11867
 
11868
;; This pattern can't accept a variable shift count, since shifts by
11869
;; zero don't affect the flags.  We assume that shifts by constant
11870
;; zero are optimized away.
11871
(define_insn "*ashrqi3_cmp"
11872
  [(set (reg FLAGS_REG)
11873
        (compare
11874
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11875
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11876
          (const_int 0)))
11877
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11878
        (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11879
  "ix86_match_ccmode (insn, CCGOCmode)
11880
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11881
   && (optimize_size
11882
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11883
  "sar{b}\t{%2, %0|%0, %2}"
11884
  [(set_attr "type" "ishift")
11885
   (set_attr "mode" "QI")])
11886
 
11887
(define_insn "*ashrqi3_cconly"
11888
  [(set (reg FLAGS_REG)
11889
        (compare
11890
          (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11891
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11892
          (const_int 0)))
11893
   (clobber (match_scratch:QI 0 "=q"))]
11894
  "ix86_match_ccmode (insn, CCGOCmode)
11895
   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11896
   && (optimize_size
11897
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11898
  "sar{b}\t{%2, %0|%0, %2}"
11899
  [(set_attr "type" "ishift")
11900
   (set_attr "mode" "QI")])
11901
 
11902
 
11903
;; Logical shift instructions
11904
 
11905
;; See comment above `ashldi3' about how this works.
11906
 
11907
(define_expand "lshrti3"
11908
  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11909
                   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11910
                                (match_operand:QI 2 "nonmemory_operand" "")))
11911
              (clobber (reg:CC FLAGS_REG))])]
11912
  "TARGET_64BIT"
11913
{
11914
  if (! immediate_operand (operands[2], QImode))
11915
    {
11916
      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11917
      DONE;
11918
    }
11919
  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11920
  DONE;
11921
})
11922
 
11923
(define_insn "lshrti3_1"
11924
  [(set (match_operand:TI 0 "register_operand" "=r")
11925
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11926
                     (match_operand:QI 2 "register_operand" "c")))
11927
   (clobber (match_scratch:DI 3 "=&r"))
11928
   (clobber (reg:CC FLAGS_REG))]
11929
  "TARGET_64BIT"
11930
  "#"
11931
  [(set_attr "type" "multi")])
11932
 
11933
(define_insn "*lshrti3_2"
11934
  [(set (match_operand:TI 0 "register_operand" "=r")
11935
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11936
                     (match_operand:QI 2 "immediate_operand" "O")))
11937
   (clobber (reg:CC FLAGS_REG))]
11938
  "TARGET_64BIT"
11939
  "#"
11940
  [(set_attr "type" "multi")])
11941
 
11942
(define_split
11943
  [(set (match_operand:TI 0 "register_operand" "")
11944
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11945
                     (match_operand:QI 2 "register_operand" "")))
11946
   (clobber (match_scratch:DI 3 ""))
11947
   (clobber (reg:CC FLAGS_REG))]
11948
  "TARGET_64BIT && reload_completed"
11949
  [(const_int 0)]
11950
  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11951
 
11952
(define_split
11953
  [(set (match_operand:TI 0 "register_operand" "")
11954
        (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11955
                     (match_operand:QI 2 "immediate_operand" "")))
11956
   (clobber (reg:CC FLAGS_REG))]
11957
  "TARGET_64BIT && reload_completed"
11958
  [(const_int 0)]
11959
  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11960
 
11961
(define_expand "lshrdi3"
11962
  [(set (match_operand:DI 0 "shiftdi_operand" "")
11963
        (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11964
                     (match_operand:QI 2 "nonmemory_operand" "")))]
11965
  ""
11966
  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11967
 
11968
(define_insn "*lshrdi3_1_one_bit_rex64"
11969
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11970
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11971
                     (match_operand:QI 2 "const1_operand" "")))
11972
   (clobber (reg:CC FLAGS_REG))]
11973
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11974
   && (TARGET_SHIFT1 || optimize_size)"
11975
  "shr{q}\t%0"
11976
  [(set_attr "type" "ishift")
11977
   (set (attr "length")
11978
     (if_then_else (match_operand:DI 0 "register_operand" "")
11979
        (const_string "2")
11980
        (const_string "*")))])
11981
 
11982
(define_insn "*lshrdi3_1_rex64"
11983
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11984
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11985
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11986
   (clobber (reg:CC FLAGS_REG))]
11987
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11988
  "@
11989
   shr{q}\t{%2, %0|%0, %2}
11990
   shr{q}\t{%b2, %0|%0, %b2}"
11991
  [(set_attr "type" "ishift")
11992
   (set_attr "mode" "DI")])
11993
 
11994
;; This pattern can't accept a variable shift count, since shifts by
11995
;; zero don't affect the flags.  We assume that shifts by constant
11996
;; zero are optimized away.
11997
(define_insn "*lshrdi3_cmp_one_bit_rex64"
11998
  [(set (reg FLAGS_REG)
11999
        (compare
12000
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12001
                       (match_operand:QI 2 "const1_operand" ""))
12002
          (const_int 0)))
12003
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12004
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12005
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12006
   && (TARGET_SHIFT1 || optimize_size)
12007
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12008
  "shr{q}\t%0"
12009
  [(set_attr "type" "ishift")
12010
   (set (attr "length")
12011
     (if_then_else (match_operand:DI 0 "register_operand" "")
12012
        (const_string "2")
12013
        (const_string "*")))])
12014
 
12015
(define_insn "*lshrdi3_cconly_one_bit_rex64"
12016
  [(set (reg FLAGS_REG)
12017
        (compare
12018
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12019
                       (match_operand:QI 2 "const1_operand" ""))
12020
          (const_int 0)))
12021
   (clobber (match_scratch:DI 0 "=r"))]
12022
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12023
   && (TARGET_SHIFT1 || optimize_size)
12024
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12025
  "shr{q}\t%0"
12026
  [(set_attr "type" "ishift")
12027
   (set_attr "length" "2")])
12028
 
12029
;; This pattern can't accept a variable shift count, since shifts by
12030
;; zero don't affect the flags.  We assume that shifts by constant
12031
;; zero are optimized away.
12032
(define_insn "*lshrdi3_cmp_rex64"
12033
  [(set (reg FLAGS_REG)
12034
        (compare
12035
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12036
                       (match_operand:QI 2 "const_int_operand" "e"))
12037
          (const_int 0)))
12038
   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12039
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12040
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12041
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12042
   && (optimize_size
12043
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12044
  "shr{q}\t{%2, %0|%0, %2}"
12045
  [(set_attr "type" "ishift")
12046
   (set_attr "mode" "DI")])
12047
 
12048
(define_insn "*lshrdi3_cconly_rex64"
12049
  [(set (reg FLAGS_REG)
12050
        (compare
12051
          (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052
                       (match_operand:QI 2 "const_int_operand" "e"))
12053
          (const_int 0)))
12054
   (clobber (match_scratch:DI 0 "=r"))]
12055
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12056
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12057
   && (optimize_size
12058
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12059
  "shr{q}\t{%2, %0|%0, %2}"
12060
  [(set_attr "type" "ishift")
12061
   (set_attr "mode" "DI")])
12062
 
12063
(define_insn "*lshrdi3_1"
12064
  [(set (match_operand:DI 0 "register_operand" "=r")
12065
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12066
                     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12067
   (clobber (reg:CC FLAGS_REG))]
12068
  "!TARGET_64BIT"
12069
  "#"
12070
  [(set_attr "type" "multi")])
12071
 
12072
;; By default we don't ask for a scratch register, because when DImode
12073
;; values are manipulated, registers are already at a premium.  But if
12074
;; we have one handy, we won't turn it away.
12075
(define_peephole2
12076
  [(match_scratch:SI 3 "r")
12077
   (parallel [(set (match_operand:DI 0 "register_operand" "")
12078
                   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12079
                                (match_operand:QI 2 "nonmemory_operand" "")))
12080
              (clobber (reg:CC FLAGS_REG))])
12081
   (match_dup 3)]
12082
  "!TARGET_64BIT && TARGET_CMOVE"
12083
  [(const_int 0)]
12084
  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12085
 
12086
(define_split
12087
  [(set (match_operand:DI 0 "register_operand" "")
12088
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12089
                     (match_operand:QI 2 "nonmemory_operand" "")))
12090
   (clobber (reg:CC FLAGS_REG))]
12091
  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12092
                     ? flow2_completed : reload_completed)"
12093
  [(const_int 0)]
12094
  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12095
 
12096
(define_expand "lshrsi3"
12097
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12098
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12099
                     (match_operand:QI 2 "nonmemory_operand" "")))
12100
   (clobber (reg:CC FLAGS_REG))]
12101
  ""
12102
  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12103
 
12104
(define_insn "*lshrsi3_1_one_bit"
12105
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12106
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12107
                     (match_operand:QI 2 "const1_operand" "")))
12108
   (clobber (reg:CC FLAGS_REG))]
12109
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12110
   && (TARGET_SHIFT1 || optimize_size)"
12111
  "shr{l}\t%0"
12112
  [(set_attr "type" "ishift")
12113
   (set (attr "length")
12114
     (if_then_else (match_operand:SI 0 "register_operand" "")
12115
        (const_string "2")
12116
        (const_string "*")))])
12117
 
12118
(define_insn "*lshrsi3_1_one_bit_zext"
12119
  [(set (match_operand:DI 0 "register_operand" "=r")
12120
        (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12121
                     (match_operand:QI 2 "const1_operand" "")))
12122
   (clobber (reg:CC FLAGS_REG))]
12123
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12124
   && (TARGET_SHIFT1 || optimize_size)"
12125
  "shr{l}\t%k0"
12126
  [(set_attr "type" "ishift")
12127
   (set_attr "length" "2")])
12128
 
12129
(define_insn "*lshrsi3_1"
12130
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12131
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12132
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12133
   (clobber (reg:CC FLAGS_REG))]
12134
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12135
  "@
12136
   shr{l}\t{%2, %0|%0, %2}
12137
   shr{l}\t{%b2, %0|%0, %b2}"
12138
  [(set_attr "type" "ishift")
12139
   (set_attr "mode" "SI")])
12140
 
12141
(define_insn "*lshrsi3_1_zext"
12142
  [(set (match_operand:DI 0 "register_operand" "=r,r")
12143
        (zero_extend:DI
12144
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12145
                       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12146
   (clobber (reg:CC FLAGS_REG))]
12147
  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12148
  "@
12149
   shr{l}\t{%2, %k0|%k0, %2}
12150
   shr{l}\t{%b2, %k0|%k0, %b2}"
12151
  [(set_attr "type" "ishift")
12152
   (set_attr "mode" "SI")])
12153
 
12154
;; This pattern can't accept a variable shift count, since shifts by
12155
;; zero don't affect the flags.  We assume that shifts by constant
12156
;; zero are optimized away.
12157
(define_insn "*lshrsi3_one_bit_cmp"
12158
  [(set (reg FLAGS_REG)
12159
        (compare
12160
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161
                       (match_operand:QI 2 "const1_operand" ""))
12162
          (const_int 0)))
12163
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12164
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12165
  "ix86_match_ccmode (insn, CCGOCmode)
12166
   && (TARGET_SHIFT1 || optimize_size)
12167
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12168
  "shr{l}\t%0"
12169
  [(set_attr "type" "ishift")
12170
   (set (attr "length")
12171
     (if_then_else (match_operand:SI 0 "register_operand" "")
12172
        (const_string "2")
12173
        (const_string "*")))])
12174
 
12175
(define_insn "*lshrsi3_one_bit_cconly"
12176
  [(set (reg FLAGS_REG)
12177
        (compare
12178
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12179
                       (match_operand:QI 2 "const1_operand" ""))
12180
          (const_int 0)))
12181
   (clobber (match_scratch:SI 0 "=r"))]
12182
  "ix86_match_ccmode (insn, CCGOCmode)
12183
   && (TARGET_SHIFT1 || optimize_size)
12184
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12185
  "shr{l}\t%0"
12186
  [(set_attr "type" "ishift")
12187
   (set_attr "length" "2")])
12188
 
12189
(define_insn "*lshrsi3_cmp_one_bit_zext"
12190
  [(set (reg FLAGS_REG)
12191
        (compare
12192
          (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12193
                       (match_operand:QI 2 "const1_operand" ""))
12194
          (const_int 0)))
12195
   (set (match_operand:DI 0 "register_operand" "=r")
12196
        (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12197
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12198
   && (TARGET_SHIFT1 || optimize_size)
12199
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12200
  "shr{l}\t%k0"
12201
  [(set_attr "type" "ishift")
12202
   (set_attr "length" "2")])
12203
 
12204
;; This pattern can't accept a variable shift count, since shifts by
12205
;; zero don't affect the flags.  We assume that shifts by constant
12206
;; zero are optimized away.
12207
(define_insn "*lshrsi3_cmp"
12208
  [(set (reg FLAGS_REG)
12209
        (compare
12210
          (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12211
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12212
          (const_int 0)))
12213
   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12214
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12215
  "ix86_match_ccmode (insn, CCGOCmode)
12216
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12217
   && (optimize_size
12218
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12219
  "shr{l}\t{%2, %0|%0, %2}"
12220
  [(set_attr "type" "ishift")
12221
   (set_attr "mode" "SI")])
12222
 
12223
(define_insn "*lshrsi3_cconly"
12224
  [(set (reg FLAGS_REG)
12225
      (compare
12226
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227
                     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12228
        (const_int 0)))
12229
   (clobber (match_scratch:SI 0 "=r"))]
12230
  "ix86_match_ccmode (insn, CCGOCmode)
12231
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12232
   && (optimize_size
12233
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12234
  "shr{l}\t{%2, %0|%0, %2}"
12235
  [(set_attr "type" "ishift")
12236
   (set_attr "mode" "SI")])
12237
 
12238
(define_insn "*lshrsi3_cmp_zext"
12239
  [(set (reg FLAGS_REG)
12240
        (compare
12241
          (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12242
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12243
          (const_int 0)))
12244
   (set (match_operand:DI 0 "register_operand" "=r")
12245
        (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12246
  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12247
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12248
   && (optimize_size
12249
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12250
  "shr{l}\t{%2, %k0|%k0, %2}"
12251
  [(set_attr "type" "ishift")
12252
   (set_attr "mode" "SI")])
12253
 
12254
(define_expand "lshrhi3"
12255
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12256
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12257
                     (match_operand:QI 2 "nonmemory_operand" "")))
12258
   (clobber (reg:CC FLAGS_REG))]
12259
  "TARGET_HIMODE_MATH"
12260
  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12261
 
12262
(define_insn "*lshrhi3_1_one_bit"
12263
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12264
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12265
                     (match_operand:QI 2 "const1_operand" "")))
12266
   (clobber (reg:CC FLAGS_REG))]
12267
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12268
   && (TARGET_SHIFT1 || optimize_size)"
12269
  "shr{w}\t%0"
12270
  [(set_attr "type" "ishift")
12271
   (set (attr "length")
12272
     (if_then_else (match_operand 0 "register_operand" "")
12273
        (const_string "2")
12274
        (const_string "*")))])
12275
 
12276
(define_insn "*lshrhi3_1"
12277
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12278
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12279
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12280
   (clobber (reg:CC FLAGS_REG))]
12281
  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12282
  "@
12283
   shr{w}\t{%2, %0|%0, %2}
12284
   shr{w}\t{%b2, %0|%0, %b2}"
12285
  [(set_attr "type" "ishift")
12286
   (set_attr "mode" "HI")])
12287
 
12288
;; This pattern can't accept a variable shift count, since shifts by
12289
;; zero don't affect the flags.  We assume that shifts by constant
12290
;; zero are optimized away.
12291
(define_insn "*lshrhi3_one_bit_cmp"
12292
  [(set (reg FLAGS_REG)
12293
        (compare
12294
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12295
                       (match_operand:QI 2 "const1_operand" ""))
12296
          (const_int 0)))
12297
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12298
        (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12299
  "ix86_match_ccmode (insn, CCGOCmode)
12300
   && (TARGET_SHIFT1 || optimize_size)
12301
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12302
  "shr{w}\t%0"
12303
  [(set_attr "type" "ishift")
12304
   (set (attr "length")
12305
     (if_then_else (match_operand:SI 0 "register_operand" "")
12306
        (const_string "2")
12307
        (const_string "*")))])
12308
 
12309
(define_insn "*lshrhi3_one_bit_cconly"
12310
  [(set (reg FLAGS_REG)
12311
        (compare
12312
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12313
                       (match_operand:QI 2 "const1_operand" ""))
12314
          (const_int 0)))
12315
   (clobber (match_scratch:HI 0 "=r"))]
12316
  "ix86_match_ccmode (insn, CCGOCmode)
12317
   && (TARGET_SHIFT1 || optimize_size)
12318
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12319
  "shr{w}\t%0"
12320
  [(set_attr "type" "ishift")
12321
   (set_attr "length" "2")])
12322
 
12323
;; This pattern can't accept a variable shift count, since shifts by
12324
;; zero don't affect the flags.  We assume that shifts by constant
12325
;; zero are optimized away.
12326
(define_insn "*lshrhi3_cmp"
12327
  [(set (reg FLAGS_REG)
12328
        (compare
12329
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12330
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331
          (const_int 0)))
12332
   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12333
        (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12334
  "ix86_match_ccmode (insn, CCGOCmode)
12335
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12336
   && (optimize_size
12337
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12338
  "shr{w}\t{%2, %0|%0, %2}"
12339
  [(set_attr "type" "ishift")
12340
   (set_attr "mode" "HI")])
12341
 
12342
(define_insn "*lshrhi3_cconly"
12343
  [(set (reg FLAGS_REG)
12344
        (compare
12345
          (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12346
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347
          (const_int 0)))
12348
   (clobber (match_scratch:HI 0 "=r"))]
12349
  "ix86_match_ccmode (insn, CCGOCmode)
12350
   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351
   && (optimize_size
12352
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353
  "shr{w}\t{%2, %0|%0, %2}"
12354
  [(set_attr "type" "ishift")
12355
   (set_attr "mode" "HI")])
12356
 
12357
(define_expand "lshrqi3"
12358
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12359
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12360
                     (match_operand:QI 2 "nonmemory_operand" "")))
12361
   (clobber (reg:CC FLAGS_REG))]
12362
  "TARGET_QIMODE_MATH"
12363
  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12364
 
12365
(define_insn "*lshrqi3_1_one_bit"
12366
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12367
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12368
                     (match_operand:QI 2 "const1_operand" "")))
12369
   (clobber (reg:CC FLAGS_REG))]
12370
  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12371
   && (TARGET_SHIFT1 || optimize_size)"
12372
  "shr{b}\t%0"
12373
  [(set_attr "type" "ishift")
12374
   (set (attr "length")
12375
     (if_then_else (match_operand 0 "register_operand" "")
12376
        (const_string "2")
12377
        (const_string "*")))])
12378
 
12379
(define_insn "*lshrqi3_1_one_bit_slp"
12380
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12381
        (lshiftrt:QI (match_dup 0)
12382
                     (match_operand:QI 1 "const1_operand" "")))
12383
   (clobber (reg:CC FLAGS_REG))]
12384
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12385
   && (TARGET_SHIFT1 || optimize_size)"
12386
  "shr{b}\t%0"
12387
  [(set_attr "type" "ishift1")
12388
   (set (attr "length")
12389
     (if_then_else (match_operand 0 "register_operand" "")
12390
        (const_string "2")
12391
        (const_string "*")))])
12392
 
12393
(define_insn "*lshrqi3_1"
12394
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12395
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12396
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12397
   (clobber (reg:CC FLAGS_REG))]
12398
  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12399
  "@
12400
   shr{b}\t{%2, %0|%0, %2}
12401
   shr{b}\t{%b2, %0|%0, %b2}"
12402
  [(set_attr "type" "ishift")
12403
   (set_attr "mode" "QI")])
12404
 
12405
(define_insn "*lshrqi3_1_slp"
12406
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12407
        (lshiftrt:QI (match_dup 0)
12408
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12409
   (clobber (reg:CC FLAGS_REG))]
12410
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12411
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12412
  "@
12413
   shr{b}\t{%1, %0|%0, %1}
12414
   shr{b}\t{%b1, %0|%0, %b1}"
12415
  [(set_attr "type" "ishift1")
12416
   (set_attr "mode" "QI")])
12417
 
12418
;; This pattern can't accept a variable shift count, since shifts by
12419
;; zero don't affect the flags.  We assume that shifts by constant
12420
;; zero are optimized away.
12421
(define_insn "*lshrqi2_one_bit_cmp"
12422
  [(set (reg FLAGS_REG)
12423
        (compare
12424
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12425
                       (match_operand:QI 2 "const1_operand" ""))
12426
          (const_int 0)))
12427
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12428
        (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12429
  "ix86_match_ccmode (insn, CCGOCmode)
12430
   && (TARGET_SHIFT1 || optimize_size)
12431
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12432
  "shr{b}\t%0"
12433
  [(set_attr "type" "ishift")
12434
   (set (attr "length")
12435
     (if_then_else (match_operand:SI 0 "register_operand" "")
12436
        (const_string "2")
12437
        (const_string "*")))])
12438
 
12439
(define_insn "*lshrqi2_one_bit_cconly"
12440
  [(set (reg FLAGS_REG)
12441
        (compare
12442
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12443
                       (match_operand:QI 2 "const1_operand" ""))
12444
          (const_int 0)))
12445
   (clobber (match_scratch:QI 0 "=q"))]
12446
  "ix86_match_ccmode (insn, CCGOCmode)
12447
   && (TARGET_SHIFT1 || optimize_size)
12448
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12449
  "shr{b}\t%0"
12450
  [(set_attr "type" "ishift")
12451
   (set_attr "length" "2")])
12452
 
12453
;; This pattern can't accept a variable shift count, since shifts by
12454
;; zero don't affect the flags.  We assume that shifts by constant
12455
;; zero are optimized away.
12456
(define_insn "*lshrqi2_cmp"
12457
  [(set (reg FLAGS_REG)
12458
        (compare
12459
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12460
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12461
          (const_int 0)))
12462
   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12463
        (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12464
  "ix86_match_ccmode (insn, CCGOCmode)
12465
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12466
   && (optimize_size
12467
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12468
  "shr{b}\t{%2, %0|%0, %2}"
12469
  [(set_attr "type" "ishift")
12470
   (set_attr "mode" "QI")])
12471
 
12472
(define_insn "*lshrqi2_cconly"
12473
  [(set (reg FLAGS_REG)
12474
        (compare
12475
          (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476
                       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12477
          (const_int 0)))
12478
   (clobber (match_scratch:QI 0 "=q"))]
12479
  "ix86_match_ccmode (insn, CCGOCmode)
12480
   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12481
   && (optimize_size
12482
       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12483
  "shr{b}\t{%2, %0|%0, %2}"
12484
  [(set_attr "type" "ishift")
12485
   (set_attr "mode" "QI")])
12486
 
12487
;; Rotate instructions
12488
 
12489
(define_expand "rotldi3"
12490
  [(set (match_operand:DI 0 "shiftdi_operand" "")
12491
        (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12492
                   (match_operand:QI 2 "nonmemory_operand" "")))
12493
   (clobber (reg:CC FLAGS_REG))]
12494
 ""
12495
{
12496
  if (TARGET_64BIT)
12497
    {
12498
      ix86_expand_binary_operator (ROTATE, DImode, operands);
12499
      DONE;
12500
    }
12501
  if (!const_1_to_31_operand (operands[2], VOIDmode))
12502
    FAIL;
12503
  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12504
  DONE;
12505
})
12506
 
12507
;; Implement rotation using two double-precision shift instructions
12508
;; and a scratch register.
12509
(define_insn_and_split "ix86_rotldi3"
12510
 [(set (match_operand:DI 0 "register_operand" "=r")
12511
       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12512
                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12513
  (clobber (reg:CC FLAGS_REG))
12514
  (clobber (match_scratch:SI 3 "=&r"))]
12515
 "!TARGET_64BIT"
12516
 ""
12517
 "&& reload_completed"
12518
 [(set (match_dup 3) (match_dup 4))
12519
  (parallel
12520
   [(set (match_dup 4)
12521
         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12522
                 (lshiftrt:SI (match_dup 5)
12523
                              (minus:QI (const_int 32) (match_dup 2)))))
12524
    (clobber (reg:CC FLAGS_REG))])
12525
  (parallel
12526
   [(set (match_dup 5)
12527
         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12528
                 (lshiftrt:SI (match_dup 3)
12529
                              (minus:QI (const_int 32) (match_dup 2)))))
12530
    (clobber (reg:CC FLAGS_REG))])]
12531
 "split_di (operands, 1, operands + 4, operands + 5);")
12532
 
12533
(define_insn "*rotlsi3_1_one_bit_rex64"
12534
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12535
        (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12536
                   (match_operand:QI 2 "const1_operand" "")))
12537
   (clobber (reg:CC FLAGS_REG))]
12538
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12539
   && (TARGET_SHIFT1 || optimize_size)"
12540
  "rol{q}\t%0"
12541
  [(set_attr "type" "rotate")
12542
   (set (attr "length")
12543
     (if_then_else (match_operand:DI 0 "register_operand" "")
12544
        (const_string "2")
12545
        (const_string "*")))])
12546
 
12547
(define_insn "*rotldi3_1_rex64"
12548
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12549
        (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12550
                   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12551
   (clobber (reg:CC FLAGS_REG))]
12552
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12553
  "@
12554
   rol{q}\t{%2, %0|%0, %2}
12555
   rol{q}\t{%b2, %0|%0, %b2}"
12556
  [(set_attr "type" "rotate")
12557
   (set_attr "mode" "DI")])
12558
 
12559
(define_expand "rotlsi3"
12560
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12561
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12562
                   (match_operand:QI 2 "nonmemory_operand" "")))
12563
   (clobber (reg:CC FLAGS_REG))]
12564
  ""
12565
  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12566
 
12567
(define_insn "*rotlsi3_1_one_bit"
12568
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12569
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12570
                   (match_operand:QI 2 "const1_operand" "")))
12571
   (clobber (reg:CC FLAGS_REG))]
12572
  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12573
   && (TARGET_SHIFT1 || optimize_size)"
12574
  "rol{l}\t%0"
12575
  [(set_attr "type" "rotate")
12576
   (set (attr "length")
12577
     (if_then_else (match_operand:SI 0 "register_operand" "")
12578
        (const_string "2")
12579
        (const_string "*")))])
12580
 
12581
(define_insn "*rotlsi3_1_one_bit_zext"
12582
  [(set (match_operand:DI 0 "register_operand" "=r")
12583
        (zero_extend:DI
12584
          (rotate:SI (match_operand:SI 1 "register_operand" "0")
12585
                     (match_operand:QI 2 "const1_operand" ""))))
12586
   (clobber (reg:CC FLAGS_REG))]
12587
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12588
   && (TARGET_SHIFT1 || optimize_size)"
12589
  "rol{l}\t%k0"
12590
  [(set_attr "type" "rotate")
12591
   (set_attr "length" "2")])
12592
 
12593
(define_insn "*rotlsi3_1"
12594
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12595
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12596
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12597
   (clobber (reg:CC FLAGS_REG))]
12598
  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12599
  "@
12600
   rol{l}\t{%2, %0|%0, %2}
12601
   rol{l}\t{%b2, %0|%0, %b2}"
12602
  [(set_attr "type" "rotate")
12603
   (set_attr "mode" "SI")])
12604
 
12605
(define_insn "*rotlsi3_1_zext"
12606
  [(set (match_operand:DI 0 "register_operand" "=r,r")
12607
        (zero_extend:DI
12608
          (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12609
                     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12610
   (clobber (reg:CC FLAGS_REG))]
12611
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12612
  "@
12613
   rol{l}\t{%2, %k0|%k0, %2}
12614
   rol{l}\t{%b2, %k0|%k0, %b2}"
12615
  [(set_attr "type" "rotate")
12616
   (set_attr "mode" "SI")])
12617
 
12618
(define_expand "rotlhi3"
12619
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12620
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12621
                   (match_operand:QI 2 "nonmemory_operand" "")))
12622
   (clobber (reg:CC FLAGS_REG))]
12623
  "TARGET_HIMODE_MATH"
12624
  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12625
 
12626
(define_insn "*rotlhi3_1_one_bit"
12627
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12628
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12629
                   (match_operand:QI 2 "const1_operand" "")))
12630
   (clobber (reg:CC FLAGS_REG))]
12631
  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12632
   && (TARGET_SHIFT1 || optimize_size)"
12633
  "rol{w}\t%0"
12634
  [(set_attr "type" "rotate")
12635
   (set (attr "length")
12636
     (if_then_else (match_operand 0 "register_operand" "")
12637
        (const_string "2")
12638
        (const_string "*")))])
12639
 
12640
(define_insn "*rotlhi3_1"
12641
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12642
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12643
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12644
   (clobber (reg:CC FLAGS_REG))]
12645
  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12646
  "@
12647
   rol{w}\t{%2, %0|%0, %2}
12648
   rol{w}\t{%b2, %0|%0, %b2}"
12649
  [(set_attr "type" "rotate")
12650
   (set_attr "mode" "HI")])
12651
 
12652
(define_expand "rotlqi3"
12653
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12654
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12655
                   (match_operand:QI 2 "nonmemory_operand" "")))
12656
   (clobber (reg:CC FLAGS_REG))]
12657
  "TARGET_QIMODE_MATH"
12658
  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12659
 
12660
(define_insn "*rotlqi3_1_one_bit_slp"
12661
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12662
        (rotate:QI (match_dup 0)
12663
                   (match_operand:QI 1 "const1_operand" "")))
12664
   (clobber (reg:CC FLAGS_REG))]
12665
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12666
   && (TARGET_SHIFT1 || optimize_size)"
12667
  "rol{b}\t%0"
12668
  [(set_attr "type" "rotate1")
12669
   (set (attr "length")
12670
     (if_then_else (match_operand 0 "register_operand" "")
12671
        (const_string "2")
12672
        (const_string "*")))])
12673
 
12674
(define_insn "*rotlqi3_1_one_bit"
12675
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12676
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12677
                   (match_operand:QI 2 "const1_operand" "")))
12678
   (clobber (reg:CC FLAGS_REG))]
12679
  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12680
   && (TARGET_SHIFT1 || optimize_size)"
12681
  "rol{b}\t%0"
12682
  [(set_attr "type" "rotate")
12683
   (set (attr "length")
12684
     (if_then_else (match_operand 0 "register_operand" "")
12685
        (const_string "2")
12686
        (const_string "*")))])
12687
 
12688
(define_insn "*rotlqi3_1_slp"
12689
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12690
        (rotate:QI (match_dup 0)
12691
                   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12692
   (clobber (reg:CC FLAGS_REG))]
12693
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12694
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12695
  "@
12696
   rol{b}\t{%1, %0|%0, %1}
12697
   rol{b}\t{%b1, %0|%0, %b1}"
12698
  [(set_attr "type" "rotate1")
12699
   (set_attr "mode" "QI")])
12700
 
12701
(define_insn "*rotlqi3_1"
12702
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12703
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12704
                   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12705
   (clobber (reg:CC FLAGS_REG))]
12706
  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12707
  "@
12708
   rol{b}\t{%2, %0|%0, %2}
12709
   rol{b}\t{%b2, %0|%0, %b2}"
12710
  [(set_attr "type" "rotate")
12711
   (set_attr "mode" "QI")])
12712
 
12713
(define_expand "rotrdi3"
12714
  [(set (match_operand:DI 0 "shiftdi_operand" "")
12715
        (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12716
                   (match_operand:QI 2 "nonmemory_operand" "")))
12717
   (clobber (reg:CC FLAGS_REG))]
12718
 ""
12719
{
12720
  if (TARGET_64BIT)
12721
    {
12722
      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12723
      DONE;
12724
    }
12725
  if (!const_1_to_31_operand (operands[2], VOIDmode))
12726
    FAIL;
12727
  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12728
  DONE;
12729
})
12730
 
12731
;; Implement rotation using two double-precision shift instructions
12732
;; and a scratch register.
12733
(define_insn_and_split "ix86_rotrdi3"
12734
 [(set (match_operand:DI 0 "register_operand" "=r")
12735
       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12736
                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12737
  (clobber (reg:CC FLAGS_REG))
12738
  (clobber (match_scratch:SI 3 "=&r"))]
12739
 "!TARGET_64BIT"
12740
 ""
12741
 "&& reload_completed"
12742
 [(set (match_dup 3) (match_dup 4))
12743
  (parallel
12744
   [(set (match_dup 4)
12745
         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12746
                 (ashift:SI (match_dup 5)
12747
                            (minus:QI (const_int 32) (match_dup 2)))))
12748
    (clobber (reg:CC FLAGS_REG))])
12749
  (parallel
12750
   [(set (match_dup 5)
12751
         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12752
                 (ashift:SI (match_dup 3)
12753
                            (minus:QI (const_int 32) (match_dup 2)))))
12754
    (clobber (reg:CC FLAGS_REG))])]
12755
 "split_di (operands, 1, operands + 4, operands + 5);")
12756
 
12757
(define_insn "*rotrdi3_1_one_bit_rex64"
12758
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12759
        (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12760
                     (match_operand:QI 2 "const1_operand" "")))
12761
   (clobber (reg:CC FLAGS_REG))]
12762
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12763
   && (TARGET_SHIFT1 || optimize_size)"
12764
  "ror{q}\t%0"
12765
  [(set_attr "type" "rotate")
12766
   (set (attr "length")
12767
     (if_then_else (match_operand:DI 0 "register_operand" "")
12768
        (const_string "2")
12769
        (const_string "*")))])
12770
 
12771
(define_insn "*rotrdi3_1_rex64"
12772
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12773
        (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12774
                     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12775
   (clobber (reg:CC FLAGS_REG))]
12776
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12777
  "@
12778
   ror{q}\t{%2, %0|%0, %2}
12779
   ror{q}\t{%b2, %0|%0, %b2}"
12780
  [(set_attr "type" "rotate")
12781
   (set_attr "mode" "DI")])
12782
 
12783
(define_expand "rotrsi3"
12784
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12785
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12786
                     (match_operand:QI 2 "nonmemory_operand" "")))
12787
   (clobber (reg:CC FLAGS_REG))]
12788
  ""
12789
  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12790
 
12791
(define_insn "*rotrsi3_1_one_bit"
12792
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12793
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12794
                     (match_operand:QI 2 "const1_operand" "")))
12795
   (clobber (reg:CC FLAGS_REG))]
12796
  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12797
   && (TARGET_SHIFT1 || optimize_size)"
12798
  "ror{l}\t%0"
12799
  [(set_attr "type" "rotate")
12800
   (set (attr "length")
12801
     (if_then_else (match_operand:SI 0 "register_operand" "")
12802
        (const_string "2")
12803
        (const_string "*")))])
12804
 
12805
(define_insn "*rotrsi3_1_one_bit_zext"
12806
  [(set (match_operand:DI 0 "register_operand" "=r")
12807
        (zero_extend:DI
12808
          (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12809
                       (match_operand:QI 2 "const1_operand" ""))))
12810
   (clobber (reg:CC FLAGS_REG))]
12811
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12812
   && (TARGET_SHIFT1 || optimize_size)"
12813
  "ror{l}\t%k0"
12814
  [(set_attr "type" "rotate")
12815
   (set (attr "length")
12816
     (if_then_else (match_operand:SI 0 "register_operand" "")
12817
        (const_string "2")
12818
        (const_string "*")))])
12819
 
12820
(define_insn "*rotrsi3_1"
12821
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12822
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12823
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12824
   (clobber (reg:CC FLAGS_REG))]
12825
  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12826
  "@
12827
   ror{l}\t{%2, %0|%0, %2}
12828
   ror{l}\t{%b2, %0|%0, %b2}"
12829
  [(set_attr "type" "rotate")
12830
   (set_attr "mode" "SI")])
12831
 
12832
(define_insn "*rotrsi3_1_zext"
12833
  [(set (match_operand:DI 0 "register_operand" "=r,r")
12834
        (zero_extend:DI
12835
          (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12836
                       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12837
   (clobber (reg:CC FLAGS_REG))]
12838
  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12839
  "@
12840
   ror{l}\t{%2, %k0|%k0, %2}
12841
   ror{l}\t{%b2, %k0|%k0, %b2}"
12842
  [(set_attr "type" "rotate")
12843
   (set_attr "mode" "SI")])
12844
 
12845
(define_expand "rotrhi3"
12846
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12847
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12848
                     (match_operand:QI 2 "nonmemory_operand" "")))
12849
   (clobber (reg:CC FLAGS_REG))]
12850
  "TARGET_HIMODE_MATH"
12851
  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12852
 
12853
(define_insn "*rotrhi3_one_bit"
12854
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12855
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12856
                     (match_operand:QI 2 "const1_operand" "")))
12857
   (clobber (reg:CC FLAGS_REG))]
12858
  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12859
   && (TARGET_SHIFT1 || optimize_size)"
12860
  "ror{w}\t%0"
12861
  [(set_attr "type" "rotate")
12862
   (set (attr "length")
12863
     (if_then_else (match_operand 0 "register_operand" "")
12864
        (const_string "2")
12865
        (const_string "*")))])
12866
 
12867
(define_insn "*rotrhi3"
12868
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12869
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12870
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12871
   (clobber (reg:CC FLAGS_REG))]
12872
  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12873
  "@
12874
   ror{w}\t{%2, %0|%0, %2}
12875
   ror{w}\t{%b2, %0|%0, %b2}"
12876
  [(set_attr "type" "rotate")
12877
   (set_attr "mode" "HI")])
12878
 
12879
(define_expand "rotrqi3"
12880
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12881
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12882
                     (match_operand:QI 2 "nonmemory_operand" "")))
12883
   (clobber (reg:CC FLAGS_REG))]
12884
  "TARGET_QIMODE_MATH"
12885
  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12886
 
12887
(define_insn "*rotrqi3_1_one_bit"
12888
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12889
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12890
                     (match_operand:QI 2 "const1_operand" "")))
12891
   (clobber (reg:CC FLAGS_REG))]
12892
  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12893
   && (TARGET_SHIFT1 || optimize_size)"
12894
  "ror{b}\t%0"
12895
  [(set_attr "type" "rotate")
12896
   (set (attr "length")
12897
     (if_then_else (match_operand 0 "register_operand" "")
12898
        (const_string "2")
12899
        (const_string "*")))])
12900
 
12901
(define_insn "*rotrqi3_1_one_bit_slp"
12902
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12903
        (rotatert:QI (match_dup 0)
12904
                     (match_operand:QI 1 "const1_operand" "")))
12905
   (clobber (reg:CC FLAGS_REG))]
12906
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12907
   && (TARGET_SHIFT1 || optimize_size)"
12908
  "ror{b}\t%0"
12909
  [(set_attr "type" "rotate1")
12910
   (set (attr "length")
12911
     (if_then_else (match_operand 0 "register_operand" "")
12912
        (const_string "2")
12913
        (const_string "*")))])
12914
 
12915
(define_insn "*rotrqi3_1"
12916
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12917
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12918
                     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12919
   (clobber (reg:CC FLAGS_REG))]
12920
  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12921
  "@
12922
   ror{b}\t{%2, %0|%0, %2}
12923
   ror{b}\t{%b2, %0|%0, %b2}"
12924
  [(set_attr "type" "rotate")
12925
   (set_attr "mode" "QI")])
12926
 
12927
(define_insn "*rotrqi3_1_slp"
12928
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12929
        (rotatert:QI (match_dup 0)
12930
                     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12931
   (clobber (reg:CC FLAGS_REG))]
12932
  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12933
   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12934
  "@
12935
   ror{b}\t{%1, %0|%0, %1}
12936
   ror{b}\t{%b1, %0|%0, %b1}"
12937
  [(set_attr "type" "rotate1")
12938
   (set_attr "mode" "QI")])
12939
 
12940
;; Bit set / bit test instructions
12941
 
12942
(define_expand "extv"
12943
  [(set (match_operand:SI 0 "register_operand" "")
12944
        (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12945
                         (match_operand:SI 2 "const8_operand" "")
12946
                         (match_operand:SI 3 "const8_operand" "")))]
12947
  ""
12948
{
12949
  /* Handle extractions from %ah et al.  */
12950
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12951
    FAIL;
12952
 
12953
  /* From mips.md: extract_bit_field doesn't verify that our source
12954
     matches the predicate, so check it again here.  */
12955
  if (! ext_register_operand (operands[1], VOIDmode))
12956
    FAIL;
12957
})
12958
 
12959
(define_expand "extzv"
12960
  [(set (match_operand:SI 0 "register_operand" "")
12961
        (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12962
                         (match_operand:SI 2 "const8_operand" "")
12963
                         (match_operand:SI 3 "const8_operand" "")))]
12964
  ""
12965
{
12966
  /* Handle extractions from %ah et al.  */
12967
  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12968
    FAIL;
12969
 
12970
  /* From mips.md: extract_bit_field doesn't verify that our source
12971
     matches the predicate, so check it again here.  */
12972
  if (! ext_register_operand (operands[1], VOIDmode))
12973
    FAIL;
12974
})
12975
 
12976
(define_expand "insv"
12977
  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12978
                      (match_operand 1 "const8_operand" "")
12979
                      (match_operand 2 "const8_operand" ""))
12980
        (match_operand 3 "register_operand" ""))]
12981
  ""
12982
{
12983
  /* Handle insertions to %ah et al.  */
12984
  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12985
    FAIL;
12986
 
12987
  /* From mips.md: insert_bit_field doesn't verify that our source
12988
     matches the predicate, so check it again here.  */
12989
  if (! ext_register_operand (operands[0], VOIDmode))
12990
    FAIL;
12991
 
12992
  if (TARGET_64BIT)
12993
    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12994
  else
12995
    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12996
 
12997
  DONE;
12998
})
12999
 
13000
;; %%% bts, btr, btc, bt.
13001
;; In general these instructions are *slow* when applied to memory,
13002
;; since they enforce atomic operation.  When applied to registers,
13003
;; it depends on the cpu implementation.  They're never faster than
13004
;; the corresponding and/ior/xor operations, so with 32-bit there's
13005
;; no point.  But in 64-bit, we can't hold the relevant immediates
13006
;; within the instruction itself, so operating on bits in the high
13007
;; 32-bits of a register becomes easier.
13008
;;
13009
;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13010
;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13011
;; negdf respectively, so they can never be disabled entirely.
13012
 
13013
(define_insn "*btsq"
13014
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13015
                         (const_int 1)
13016
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
13017
        (const_int 1))
13018
   (clobber (reg:CC FLAGS_REG))]
13019
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13020
  "bts{q} %1,%0"
13021
  [(set_attr "type" "alu1")])
13022
 
13023
(define_insn "*btrq"
13024
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13025
                         (const_int 1)
13026
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
13027
        (const_int 0))
13028
   (clobber (reg:CC FLAGS_REG))]
13029
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13030
  "btr{q} %1,%0"
13031
  [(set_attr "type" "alu1")])
13032
 
13033
(define_insn "*btcq"
13034
  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13035
                         (const_int 1)
13036
                         (match_operand:DI 1 "const_0_to_63_operand" ""))
13037
        (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13038
   (clobber (reg:CC FLAGS_REG))]
13039
  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13040
  "btc{q} %1,%0"
13041
  [(set_attr "type" "alu1")])
13042
 
13043
;; Allow Nocona to avoid these instructions if a register is available.
13044
 
13045
(define_peephole2
13046
  [(match_scratch:DI 2 "r")
13047
   (parallel [(set (zero_extract:DI
13048
                     (match_operand:DI 0 "register_operand" "")
13049
                     (const_int 1)
13050
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
13051
                   (const_int 1))
13052
              (clobber (reg:CC FLAGS_REG))])]
13053
  "TARGET_64BIT && !TARGET_USE_BT"
13054
  [(const_int 0)]
13055
{
13056
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13057
  rtx op1;
13058
 
13059
  if (HOST_BITS_PER_WIDE_INT >= 64)
13060
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13061
  else if (i < HOST_BITS_PER_WIDE_INT)
13062
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13063
  else
13064
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13065
 
13066
  op1 = immed_double_const (lo, hi, DImode);
13067
  if (i >= 31)
13068
    {
13069
      emit_move_insn (operands[2], op1);
13070
      op1 = operands[2];
13071
    }
13072
 
13073
  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13074
  DONE;
13075
})
13076
 
13077
(define_peephole2
13078
  [(match_scratch:DI 2 "r")
13079
   (parallel [(set (zero_extract:DI
13080
                     (match_operand:DI 0 "register_operand" "")
13081
                     (const_int 1)
13082
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
13083
                   (const_int 0))
13084
              (clobber (reg:CC FLAGS_REG))])]
13085
  "TARGET_64BIT && !TARGET_USE_BT"
13086
  [(const_int 0)]
13087
{
13088
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13089
  rtx op1;
13090
 
13091
  if (HOST_BITS_PER_WIDE_INT >= 64)
13092
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13093
  else if (i < HOST_BITS_PER_WIDE_INT)
13094
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13095
  else
13096
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13097
 
13098
  op1 = immed_double_const (~lo, ~hi, DImode);
13099
  if (i >= 32)
13100
    {
13101
      emit_move_insn (operands[2], op1);
13102
      op1 = operands[2];
13103
    }
13104
 
13105
  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13106
  DONE;
13107
})
13108
 
13109
(define_peephole2
13110
  [(match_scratch:DI 2 "r")
13111
   (parallel [(set (zero_extract:DI
13112
                     (match_operand:DI 0 "register_operand" "")
13113
                     (const_int 1)
13114
                     (match_operand:DI 1 "const_0_to_63_operand" ""))
13115
              (not:DI (zero_extract:DI
13116
                        (match_dup 0) (const_int 1) (match_dup 1))))
13117
              (clobber (reg:CC FLAGS_REG))])]
13118
  "TARGET_64BIT && !TARGET_USE_BT"
13119
  [(const_int 0)]
13120
{
13121
  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13122
  rtx op1;
13123
 
13124
  if (HOST_BITS_PER_WIDE_INT >= 64)
13125
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13126
  else if (i < HOST_BITS_PER_WIDE_INT)
13127
    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13128
  else
13129
    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13130
 
13131
  op1 = immed_double_const (lo, hi, DImode);
13132
  if (i >= 31)
13133
    {
13134
      emit_move_insn (operands[2], op1);
13135
      op1 = operands[2];
13136
    }
13137
 
13138
  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13139
  DONE;
13140
})
13141
 
13142
;; Store-flag instructions.
13143
 
13144
;; For all sCOND expanders, also expand the compare or test insn that
13145
;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13146
 
13147
;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13148
;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13149
;; way, which can later delete the movzx if only QImode is needed.
13150
 
13151
(define_expand "seq"
13152
  [(set (match_operand:QI 0 "register_operand" "")
13153
        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13154
  ""
13155
  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13156
 
13157
(define_expand "sne"
13158
  [(set (match_operand:QI 0 "register_operand" "")
13159
        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13160
  ""
13161
  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13162
 
13163
(define_expand "sgt"
13164
  [(set (match_operand:QI 0 "register_operand" "")
13165
        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13166
  ""
13167
  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13168
 
13169
(define_expand "sgtu"
13170
  [(set (match_operand:QI 0 "register_operand" "")
13171
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13172
  ""
13173
  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13174
 
13175
(define_expand "slt"
13176
  [(set (match_operand:QI 0 "register_operand" "")
13177
        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13178
  ""
13179
  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13180
 
13181
(define_expand "sltu"
13182
  [(set (match_operand:QI 0 "register_operand" "")
13183
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13184
  ""
13185
  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13186
 
13187
(define_expand "sge"
13188
  [(set (match_operand:QI 0 "register_operand" "")
13189
        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13190
  ""
13191
  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13192
 
13193
(define_expand "sgeu"
13194
  [(set (match_operand:QI 0 "register_operand" "")
13195
        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13196
  ""
13197
  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13198
 
13199
(define_expand "sle"
13200
  [(set (match_operand:QI 0 "register_operand" "")
13201
        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13202
  ""
13203
  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13204
 
13205
(define_expand "sleu"
13206
  [(set (match_operand:QI 0 "register_operand" "")
13207
        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13208
  ""
13209
  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13210
 
13211
(define_expand "sunordered"
13212
  [(set (match_operand:QI 0 "register_operand" "")
13213
        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13214
  "TARGET_80387 || TARGET_SSE"
13215
  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13216
 
13217
(define_expand "sordered"
13218
  [(set (match_operand:QI 0 "register_operand" "")
13219
        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13220
  "TARGET_80387"
13221
  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13222
 
13223
(define_expand "suneq"
13224
  [(set (match_operand:QI 0 "register_operand" "")
13225
        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13226
  "TARGET_80387 || TARGET_SSE"
13227
  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13228
 
13229
(define_expand "sunge"
13230
  [(set (match_operand:QI 0 "register_operand" "")
13231
        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13232
  "TARGET_80387 || TARGET_SSE"
13233
  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13234
 
13235
(define_expand "sungt"
13236
  [(set (match_operand:QI 0 "register_operand" "")
13237
        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13238
  "TARGET_80387 || TARGET_SSE"
13239
  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13240
 
13241
(define_expand "sunle"
13242
  [(set (match_operand:QI 0 "register_operand" "")
13243
        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13244
  "TARGET_80387 || TARGET_SSE"
13245
  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13246
 
13247
(define_expand "sunlt"
13248
  [(set (match_operand:QI 0 "register_operand" "")
13249
        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13250
  "TARGET_80387 || TARGET_SSE"
13251
  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13252
 
13253
(define_expand "sltgt"
13254
  [(set (match_operand:QI 0 "register_operand" "")
13255
        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13256
  "TARGET_80387 || TARGET_SSE"
13257
  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13258
 
13259
(define_insn "*setcc_1"
13260
  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13261
        (match_operator:QI 1 "ix86_comparison_operator"
13262
          [(reg FLAGS_REG) (const_int 0)]))]
13263
  ""
13264
  "set%C1\t%0"
13265
  [(set_attr "type" "setcc")
13266
   (set_attr "mode" "QI")])
13267
 
13268
(define_insn "*setcc_2"
13269
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13270
        (match_operator:QI 1 "ix86_comparison_operator"
13271
          [(reg FLAGS_REG) (const_int 0)]))]
13272
  ""
13273
  "set%C1\t%0"
13274
  [(set_attr "type" "setcc")
13275
   (set_attr "mode" "QI")])
13276
 
13277
;; In general it is not safe to assume too much about CCmode registers,
13278
;; so simplify-rtx stops when it sees a second one.  Under certain
13279
;; conditions this is safe on x86, so help combine not create
13280
;;
13281
;;      seta    %al
13282
;;      testb   %al, %al
13283
;;      sete    %al
13284
 
13285
(define_split
13286
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13287
        (ne:QI (match_operator 1 "ix86_comparison_operator"
13288
                 [(reg FLAGS_REG) (const_int 0)])
13289
            (const_int 0)))]
13290
  ""
13291
  [(set (match_dup 0) (match_dup 1))]
13292
{
13293
  PUT_MODE (operands[1], QImode);
13294
})
13295
 
13296
(define_split
13297
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13298
        (ne:QI (match_operator 1 "ix86_comparison_operator"
13299
                 [(reg FLAGS_REG) (const_int 0)])
13300
            (const_int 0)))]
13301
  ""
13302
  [(set (match_dup 0) (match_dup 1))]
13303
{
13304
  PUT_MODE (operands[1], QImode);
13305
})
13306
 
13307
(define_split
13308
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13309
        (eq:QI (match_operator 1 "ix86_comparison_operator"
13310
                 [(reg FLAGS_REG) (const_int 0)])
13311
            (const_int 0)))]
13312
  ""
13313
  [(set (match_dup 0) (match_dup 1))]
13314
{
13315
  rtx new_op1 = copy_rtx (operands[1]);
13316
  operands[1] = new_op1;
13317
  PUT_MODE (new_op1, QImode);
13318
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13319
                                             GET_MODE (XEXP (new_op1, 0))));
13320
 
13321
  /* Make sure that (a) the CCmode we have for the flags is strong
13322
     enough for the reversed compare or (b) we have a valid FP compare.  */
13323
  if (! ix86_comparison_operator (new_op1, VOIDmode))
13324
    FAIL;
13325
})
13326
 
13327
(define_split
13328
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13329
        (eq:QI (match_operator 1 "ix86_comparison_operator"
13330
                 [(reg FLAGS_REG) (const_int 0)])
13331
            (const_int 0)))]
13332
  ""
13333
  [(set (match_dup 0) (match_dup 1))]
13334
{
13335
  rtx new_op1 = copy_rtx (operands[1]);
13336
  operands[1] = new_op1;
13337
  PUT_MODE (new_op1, QImode);
13338
  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13339
                                             GET_MODE (XEXP (new_op1, 0))));
13340
 
13341
  /* Make sure that (a) the CCmode we have for the flags is strong
13342
     enough for the reversed compare or (b) we have a valid FP compare.  */
13343
  if (! ix86_comparison_operator (new_op1, VOIDmode))
13344
    FAIL;
13345
})
13346
 
13347
;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13348
;; subsequent logical operations are used to imitate conditional moves.
13349
;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13350
;; it directly.
13351
 
13352
(define_insn "*sse_setccsf"
13353
  [(set (match_operand:SF 0 "register_operand" "=x")
13354
        (match_operator:SF 1 "sse_comparison_operator"
13355
          [(match_operand:SF 2 "register_operand" "0")
13356
           (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13357
  "TARGET_SSE"
13358
  "cmp%D1ss\t{%3, %0|%0, %3}"
13359
  [(set_attr "type" "ssecmp")
13360
   (set_attr "mode" "SF")])
13361
 
13362
(define_insn "*sse_setccdf"
13363
  [(set (match_operand:DF 0 "register_operand" "=Y")
13364
        (match_operator:DF 1 "sse_comparison_operator"
13365
          [(match_operand:DF 2 "register_operand" "0")
13366
           (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13367
  "TARGET_SSE2"
13368
  "cmp%D1sd\t{%3, %0|%0, %3}"
13369
  [(set_attr "type" "ssecmp")
13370
   (set_attr "mode" "DF")])
13371
 
13372
;; Basic conditional jump instructions.
13373
;; We ignore the overflow flag for signed branch instructions.
13374
 
13375
;; For all bCOND expanders, also expand the compare or test insn that
13376
;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13377
 
13378
(define_expand "beq"
13379
  [(set (pc)
13380
        (if_then_else (match_dup 1)
13381
                      (label_ref (match_operand 0 "" ""))
13382
                      (pc)))]
13383
  ""
13384
  "ix86_expand_branch (EQ, operands[0]); DONE;")
13385
 
13386
(define_expand "bne"
13387
  [(set (pc)
13388
        (if_then_else (match_dup 1)
13389
                      (label_ref (match_operand 0 "" ""))
13390
                      (pc)))]
13391
  ""
13392
  "ix86_expand_branch (NE, operands[0]); DONE;")
13393
 
13394
(define_expand "bgt"
13395
  [(set (pc)
13396
        (if_then_else (match_dup 1)
13397
                      (label_ref (match_operand 0 "" ""))
13398
                      (pc)))]
13399
  ""
13400
  "ix86_expand_branch (GT, operands[0]); DONE;")
13401
 
13402
(define_expand "bgtu"
13403
  [(set (pc)
13404
        (if_then_else (match_dup 1)
13405
                      (label_ref (match_operand 0 "" ""))
13406
                      (pc)))]
13407
  ""
13408
  "ix86_expand_branch (GTU, operands[0]); DONE;")
13409
 
13410
(define_expand "blt"
13411
  [(set (pc)
13412
        (if_then_else (match_dup 1)
13413
                      (label_ref (match_operand 0 "" ""))
13414
                      (pc)))]
13415
  ""
13416
  "ix86_expand_branch (LT, operands[0]); DONE;")
13417
 
13418
(define_expand "bltu"
13419
  [(set (pc)
13420
        (if_then_else (match_dup 1)
13421
                      (label_ref (match_operand 0 "" ""))
13422
                      (pc)))]
13423
  ""
13424
  "ix86_expand_branch (LTU, operands[0]); DONE;")
13425
 
13426
(define_expand "bge"
13427
  [(set (pc)
13428
        (if_then_else (match_dup 1)
13429
                      (label_ref (match_operand 0 "" ""))
13430
                      (pc)))]
13431
  ""
13432
  "ix86_expand_branch (GE, operands[0]); DONE;")
13433
 
13434
(define_expand "bgeu"
13435
  [(set (pc)
13436
        (if_then_else (match_dup 1)
13437
                      (label_ref (match_operand 0 "" ""))
13438
                      (pc)))]
13439
  ""
13440
  "ix86_expand_branch (GEU, operands[0]); DONE;")
13441
 
13442
(define_expand "ble"
13443
  [(set (pc)
13444
        (if_then_else (match_dup 1)
13445
                      (label_ref (match_operand 0 "" ""))
13446
                      (pc)))]
13447
  ""
13448
  "ix86_expand_branch (LE, operands[0]); DONE;")
13449
 
13450
(define_expand "bleu"
13451
  [(set (pc)
13452
        (if_then_else (match_dup 1)
13453
                      (label_ref (match_operand 0 "" ""))
13454
                      (pc)))]
13455
  ""
13456
  "ix86_expand_branch (LEU, operands[0]); DONE;")
13457
 
13458
(define_expand "bunordered"
13459
  [(set (pc)
13460
        (if_then_else (match_dup 1)
13461
                      (label_ref (match_operand 0 "" ""))
13462
                      (pc)))]
13463
  "TARGET_80387 || TARGET_SSE_MATH"
13464
  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13465
 
13466
(define_expand "bordered"
13467
  [(set (pc)
13468
        (if_then_else (match_dup 1)
13469
                      (label_ref (match_operand 0 "" ""))
13470
                      (pc)))]
13471
  "TARGET_80387 || TARGET_SSE_MATH"
13472
  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13473
 
13474
(define_expand "buneq"
13475
  [(set (pc)
13476
        (if_then_else (match_dup 1)
13477
                      (label_ref (match_operand 0 "" ""))
13478
                      (pc)))]
13479
  "TARGET_80387 || TARGET_SSE_MATH"
13480
  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13481
 
13482
(define_expand "bunge"
13483
  [(set (pc)
13484
        (if_then_else (match_dup 1)
13485
                      (label_ref (match_operand 0 "" ""))
13486
                      (pc)))]
13487
  "TARGET_80387 || TARGET_SSE_MATH"
13488
  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13489
 
13490
(define_expand "bungt"
13491
  [(set (pc)
13492
        (if_then_else (match_dup 1)
13493
                      (label_ref (match_operand 0 "" ""))
13494
                      (pc)))]
13495
  "TARGET_80387 || TARGET_SSE_MATH"
13496
  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13497
 
13498
(define_expand "bunle"
13499
  [(set (pc)
13500
        (if_then_else (match_dup 1)
13501
                      (label_ref (match_operand 0 "" ""))
13502
                      (pc)))]
13503
  "TARGET_80387 || TARGET_SSE_MATH"
13504
  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13505
 
13506
(define_expand "bunlt"
13507
  [(set (pc)
13508
        (if_then_else (match_dup 1)
13509
                      (label_ref (match_operand 0 "" ""))
13510
                      (pc)))]
13511
  "TARGET_80387 || TARGET_SSE_MATH"
13512
  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13513
 
13514
(define_expand "bltgt"
13515
  [(set (pc)
13516
        (if_then_else (match_dup 1)
13517
                      (label_ref (match_operand 0 "" ""))
13518
                      (pc)))]
13519
  "TARGET_80387 || TARGET_SSE_MATH"
13520
  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13521
 
13522
(define_insn "*jcc_1"
13523
  [(set (pc)
13524
        (if_then_else (match_operator 1 "ix86_comparison_operator"
13525
                                      [(reg FLAGS_REG) (const_int 0)])
13526
                      (label_ref (match_operand 0 "" ""))
13527
                      (pc)))]
13528
  ""
13529
  "%+j%C1\t%l0"
13530
  [(set_attr "type" "ibr")
13531
   (set_attr "modrm" "0")
13532
   (set (attr "length")
13533
           (if_then_else (and (ge (minus (match_dup 0) (pc))
13534
                                  (const_int -126))
13535
                              (lt (minus (match_dup 0) (pc))
13536
                                  (const_int 128)))
13537
             (const_int 2)
13538
             (const_int 6)))])
13539
 
13540
(define_insn "*jcc_2"
13541
  [(set (pc)
13542
        (if_then_else (match_operator 1 "ix86_comparison_operator"
13543
                                      [(reg FLAGS_REG) (const_int 0)])
13544
                      (pc)
13545
                      (label_ref (match_operand 0 "" ""))))]
13546
  ""
13547
  "%+j%c1\t%l0"
13548
  [(set_attr "type" "ibr")
13549
   (set_attr "modrm" "0")
13550
   (set (attr "length")
13551
           (if_then_else (and (ge (minus (match_dup 0) (pc))
13552
                                  (const_int -126))
13553
                              (lt (minus (match_dup 0) (pc))
13554
                                  (const_int 128)))
13555
             (const_int 2)
13556
             (const_int 6)))])
13557
 
13558
;; In general it is not safe to assume too much about CCmode registers,
13559
;; so simplify-rtx stops when it sees a second one.  Under certain
13560
;; conditions this is safe on x86, so help combine not create
13561
;;
13562
;;      seta    %al
13563
;;      testb   %al, %al
13564
;;      je      Lfoo
13565
 
13566
(define_split
13567
  [(set (pc)
13568
        (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13569
                                      [(reg FLAGS_REG) (const_int 0)])
13570
                          (const_int 0))
13571
                      (label_ref (match_operand 1 "" ""))
13572
                      (pc)))]
13573
  ""
13574
  [(set (pc)
13575
        (if_then_else (match_dup 0)
13576
                      (label_ref (match_dup 1))
13577
                      (pc)))]
13578
{
13579
  PUT_MODE (operands[0], VOIDmode);
13580
})
13581
 
13582
(define_split
13583
  [(set (pc)
13584
        (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13585
                                      [(reg FLAGS_REG) (const_int 0)])
13586
                          (const_int 0))
13587
                      (label_ref (match_operand 1 "" ""))
13588
                      (pc)))]
13589
  ""
13590
  [(set (pc)
13591
        (if_then_else (match_dup 0)
13592
                      (label_ref (match_dup 1))
13593
                      (pc)))]
13594
{
13595
  rtx new_op0 = copy_rtx (operands[0]);
13596
  operands[0] = new_op0;
13597
  PUT_MODE (new_op0, VOIDmode);
13598
  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13599
                                             GET_MODE (XEXP (new_op0, 0))));
13600
 
13601
  /* Make sure that (a) the CCmode we have for the flags is strong
13602
     enough for the reversed compare or (b) we have a valid FP compare.  */
13603
  if (! ix86_comparison_operator (new_op0, VOIDmode))
13604
    FAIL;
13605
})
13606
 
13607
;; Define combination compare-and-branch fp compare instructions to use
13608
;; during early optimization.  Splitting the operation apart early makes
13609
;; for bad code when we want to reverse the operation.
13610
 
13611
(define_insn "*fp_jcc_1_mixed"
13612
  [(set (pc)
13613
        (if_then_else (match_operator 0 "comparison_operator"
13614
                        [(match_operand 1 "register_operand" "f,x")
13615
                         (match_operand 2 "nonimmediate_operand" "f,xm")])
13616
          (label_ref (match_operand 3 "" ""))
13617
          (pc)))
13618
   (clobber (reg:CCFP FPSR_REG))
13619
   (clobber (reg:CCFP FLAGS_REG))]
13620
  "TARGET_MIX_SSE_I387
13621
   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13622
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13623
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13624
  "#")
13625
 
13626
(define_insn "*fp_jcc_1_sse"
13627
  [(set (pc)
13628
        (if_then_else (match_operator 0 "comparison_operator"
13629
                        [(match_operand 1 "register_operand" "x")
13630
                         (match_operand 2 "nonimmediate_operand" "xm")])
13631
          (label_ref (match_operand 3 "" ""))
13632
          (pc)))
13633
   (clobber (reg:CCFP FPSR_REG))
13634
   (clobber (reg:CCFP FLAGS_REG))]
13635
  "TARGET_SSE_MATH
13636
   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13637
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13638
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13639
  "#")
13640
 
13641
(define_insn "*fp_jcc_1_387"
13642
  [(set (pc)
13643
        (if_then_else (match_operator 0 "comparison_operator"
13644
                        [(match_operand 1 "register_operand" "f")
13645
                         (match_operand 2 "register_operand" "f")])
13646
          (label_ref (match_operand 3 "" ""))
13647
          (pc)))
13648
   (clobber (reg:CCFP FPSR_REG))
13649
   (clobber (reg:CCFP FLAGS_REG))]
13650
  "TARGET_CMOVE && TARGET_80387
13651
   && FLOAT_MODE_P (GET_MODE (operands[1]))
13652
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13653
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13654
  "#")
13655
 
13656
(define_insn "*fp_jcc_2_mixed"
13657
  [(set (pc)
13658
        (if_then_else (match_operator 0 "comparison_operator"
13659
                        [(match_operand 1 "register_operand" "f,x")
13660
                         (match_operand 2 "nonimmediate_operand" "f,xm")])
13661
          (pc)
13662
          (label_ref (match_operand 3 "" ""))))
13663
   (clobber (reg:CCFP FPSR_REG))
13664
   (clobber (reg:CCFP FLAGS_REG))]
13665
  "TARGET_MIX_SSE_I387
13666
   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13667
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13668
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13669
  "#")
13670
 
13671
(define_insn "*fp_jcc_2_sse"
13672
  [(set (pc)
13673
        (if_then_else (match_operator 0 "comparison_operator"
13674
                        [(match_operand 1 "register_operand" "x")
13675
                         (match_operand 2 "nonimmediate_operand" "xm")])
13676
          (pc)
13677
          (label_ref (match_operand 3 "" ""))))
13678
   (clobber (reg:CCFP FPSR_REG))
13679
   (clobber (reg:CCFP FLAGS_REG))]
13680
  "TARGET_SSE_MATH
13681
   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13682
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13683
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13684
  "#")
13685
 
13686
(define_insn "*fp_jcc_2_387"
13687
  [(set (pc)
13688
        (if_then_else (match_operator 0 "comparison_operator"
13689
                        [(match_operand 1 "register_operand" "f")
13690
                         (match_operand 2 "register_operand" "f")])
13691
          (pc)
13692
          (label_ref (match_operand 3 "" ""))))
13693
   (clobber (reg:CCFP FPSR_REG))
13694
   (clobber (reg:CCFP FLAGS_REG))]
13695
  "TARGET_CMOVE && TARGET_80387
13696
   && FLOAT_MODE_P (GET_MODE (operands[1]))
13697
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13698
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13699
  "#")
13700
 
13701
(define_insn "*fp_jcc_3_387"
13702
  [(set (pc)
13703
        (if_then_else (match_operator 0 "comparison_operator"
13704
                        [(match_operand 1 "register_operand" "f")
13705
                         (match_operand 2 "nonimmediate_operand" "fm")])
13706
          (label_ref (match_operand 3 "" ""))
13707
          (pc)))
13708
   (clobber (reg:CCFP FPSR_REG))
13709
   (clobber (reg:CCFP FLAGS_REG))
13710
   (clobber (match_scratch:HI 4 "=a"))]
13711
  "TARGET_80387
13712
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13713
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13714
   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13715
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13716
                      operands[1], operands[2]) == CCFPmode
13717
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13718
  "#")
13719
 
13720
(define_insn "*fp_jcc_4_387"
13721
  [(set (pc)
13722
        (if_then_else (match_operator 0 "comparison_operator"
13723
                        [(match_operand 1 "register_operand" "f")
13724
                         (match_operand 2 "nonimmediate_operand" "fm")])
13725
          (pc)
13726
          (label_ref (match_operand 3 "" ""))))
13727
   (clobber (reg:CCFP FPSR_REG))
13728
   (clobber (reg:CCFP FLAGS_REG))
13729
   (clobber (match_scratch:HI 4 "=a"))]
13730
  "TARGET_80387
13731
   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13732
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13733
   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13734
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13735
                      operands[1], operands[2]) == CCFPmode
13736
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13737
  "#")
13738
 
13739
(define_insn "*fp_jcc_5_387"
13740
  [(set (pc)
13741
        (if_then_else (match_operator 0 "comparison_operator"
13742
                        [(match_operand 1 "register_operand" "f")
13743
                         (match_operand 2 "register_operand" "f")])
13744
          (label_ref (match_operand 3 "" ""))
13745
          (pc)))
13746
   (clobber (reg:CCFP FPSR_REG))
13747
   (clobber (reg:CCFP FLAGS_REG))
13748
   (clobber (match_scratch:HI 4 "=a"))]
13749
  "TARGET_80387
13750
   && FLOAT_MODE_P (GET_MODE (operands[1]))
13751
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753
  "#")
13754
 
13755
(define_insn "*fp_jcc_6_387"
13756
  [(set (pc)
13757
        (if_then_else (match_operator 0 "comparison_operator"
13758
                        [(match_operand 1 "register_operand" "f")
13759
                         (match_operand 2 "register_operand" "f")])
13760
          (pc)
13761
          (label_ref (match_operand 3 "" ""))))
13762
   (clobber (reg:CCFP FPSR_REG))
13763
   (clobber (reg:CCFP FLAGS_REG))
13764
   (clobber (match_scratch:HI 4 "=a"))]
13765
  "TARGET_80387
13766
   && FLOAT_MODE_P (GET_MODE (operands[1]))
13767
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13769
  "#")
13770
 
13771
(define_insn "*fp_jcc_7_387"
13772
  [(set (pc)
13773
        (if_then_else (match_operator 0 "comparison_operator"
13774
                        [(match_operand 1 "register_operand" "f")
13775
                         (match_operand 2 "const0_operand" "X")])
13776
          (label_ref (match_operand 3 "" ""))
13777
          (pc)))
13778
   (clobber (reg:CCFP FPSR_REG))
13779
   (clobber (reg:CCFP FLAGS_REG))
13780
   (clobber (match_scratch:HI 4 "=a"))]
13781
  "TARGET_80387
13782
   && FLOAT_MODE_P (GET_MODE (operands[1]))
13783
   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13784
   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13785
   && SELECT_CC_MODE (GET_CODE (operands[0]),
13786
                      operands[1], operands[2]) == CCFPmode
13787
   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13788
  "#")
13789
 
13790
;; The order of operands in *fp_jcc_8_387 is forced by combine in
13791
;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13792
;; with a precedence over other operators and is always put in the first
13793
;; place. Swap condition and operands to match ficom instruction.
13794
 
13795
(define_insn "*fp_jcc_8_387"
13796
  [(set (pc)
13797
        (if_then_else (match_operator 0 "comparison_operator"
13798
                        [(match_operator 1 "float_operator"
13799
                           [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13800
                           (match_operand 3 "register_operand" "f,f")])
13801
          (label_ref (match_operand 4 "" ""))
13802
          (pc)))
13803
   (clobber (reg:CCFP FPSR_REG))
13804
   (clobber (reg:CCFP FLAGS_REG))
13805
   (clobber (match_scratch:HI 5 "=a,a"))]
13806
  "TARGET_80387 && TARGET_USE_MODE_FIOP
13807
   && FLOAT_MODE_P (GET_MODE (operands[3]))
13808
   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13809
   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13810
   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13811
   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13812
  "#")
13813
 
13814
(define_split
13815
  [(set (pc)
13816
        (if_then_else (match_operator 0 "comparison_operator"
13817
                        [(match_operand 1 "register_operand" "")
13818
                         (match_operand 2 "nonimmediate_operand" "")])
13819
          (match_operand 3 "" "")
13820
          (match_operand 4 "" "")))
13821
   (clobber (reg:CCFP FPSR_REG))
13822
   (clobber (reg:CCFP FLAGS_REG))]
13823
  "reload_completed"
13824
  [(const_int 0)]
13825
{
13826
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13827
                        operands[3], operands[4], NULL_RTX, NULL_RTX);
13828
  DONE;
13829
})
13830
 
13831
(define_split
13832
  [(set (pc)
13833
        (if_then_else (match_operator 0 "comparison_operator"
13834
                        [(match_operand 1 "register_operand" "")
13835
                         (match_operand 2 "general_operand" "")])
13836
          (match_operand 3 "" "")
13837
          (match_operand 4 "" "")))
13838
   (clobber (reg:CCFP FPSR_REG))
13839
   (clobber (reg:CCFP FLAGS_REG))
13840
   (clobber (match_scratch:HI 5 "=a"))]
13841
  "reload_completed"
13842
  [(const_int 0)]
13843
{
13844
  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13845
                        operands[3], operands[4], operands[5], NULL_RTX);
13846
  DONE;
13847
})
13848
 
13849
(define_split
13850
  [(set (pc)
13851
        (if_then_else (match_operator 0 "comparison_operator"
13852
                        [(match_operator 1 "float_operator"
13853
                           [(match_operand:X87MODEI12 2 "memory_operand" "")])
13854
                           (match_operand 3 "register_operand" "")])
13855
          (match_operand 4 "" "")
13856
          (match_operand 5 "" "")))
13857
   (clobber (reg:CCFP FPSR_REG))
13858
   (clobber (reg:CCFP FLAGS_REG))
13859
   (clobber (match_scratch:HI 6 "=a"))]
13860
  "reload_completed"
13861
  [(const_int 0)]
13862
{
13863
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13864
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13865
                        operands[3], operands[7],
13866
                        operands[4], operands[5], operands[6], NULL_RTX);
13867
  DONE;
13868
})
13869
 
13870
;; %%% Kill this when reload knows how to do it.
13871
(define_split
13872
  [(set (pc)
13873
        (if_then_else (match_operator 0 "comparison_operator"
13874
                        [(match_operator 1 "float_operator"
13875
                           [(match_operand:X87MODEI12 2 "register_operand" "")])
13876
                           (match_operand 3 "register_operand" "")])
13877
          (match_operand 4 "" "")
13878
          (match_operand 5 "" "")))
13879
   (clobber (reg:CCFP FPSR_REG))
13880
   (clobber (reg:CCFP FLAGS_REG))
13881
   (clobber (match_scratch:HI 6 "=a"))]
13882
  "reload_completed"
13883
  [(const_int 0)]
13884
{
13885
  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13886
  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13887
  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13888
                        operands[3], operands[7],
13889
                        operands[4], operands[5], operands[6], operands[2]);
13890
  DONE;
13891
})
13892
 
13893
;; Unconditional and other jump instructions
13894
 
13895
(define_insn "jump"
13896
  [(set (pc)
13897
        (label_ref (match_operand 0 "" "")))]
13898
  ""
13899
  "jmp\t%l0"
13900
  [(set_attr "type" "ibr")
13901
   (set (attr "length")
13902
           (if_then_else (and (ge (minus (match_dup 0) (pc))
13903
                                  (const_int -126))
13904
                              (lt (minus (match_dup 0) (pc))
13905
                                  (const_int 128)))
13906
             (const_int 2)
13907
             (const_int 5)))
13908
   (set_attr "modrm" "0")])
13909
 
13910
(define_expand "indirect_jump"
13911
  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13912
  ""
13913
  "")
13914
 
13915
(define_insn "*indirect_jump"
13916
  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13917
  "!TARGET_64BIT"
13918
  "jmp\t%A0"
13919
  [(set_attr "type" "ibr")
13920
   (set_attr "length_immediate" "0")])
13921
 
13922
(define_insn "*indirect_jump_rtx64"
13923
  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13924
  "TARGET_64BIT"
13925
  "jmp\t%A0"
13926
  [(set_attr "type" "ibr")
13927
   (set_attr "length_immediate" "0")])
13928
 
13929
(define_expand "tablejump"
13930
  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13931
              (use (label_ref (match_operand 1 "" "")))])]
13932
  ""
13933
{
13934
  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13935
     relative.  Convert the relative address to an absolute address.  */
13936
  if (flag_pic)
13937
    {
13938
      rtx op0, op1;
13939
      enum rtx_code code;
13940
 
13941
      if (TARGET_64BIT)
13942
        {
13943
          code = PLUS;
13944
          op0 = operands[0];
13945
          op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13946
        }
13947
      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13948
        {
13949
          code = PLUS;
13950
          op0 = operands[0];
13951
          op1 = pic_offset_table_rtx;
13952
        }
13953
      else
13954
        {
13955
          code = MINUS;
13956
          op0 = pic_offset_table_rtx;
13957
          op1 = operands[0];
13958
        }
13959
 
13960
      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13961
                                         OPTAB_DIRECT);
13962
    }
13963
})
13964
 
13965
(define_insn "*tablejump_1"
13966
  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13967
   (use (label_ref (match_operand 1 "" "")))]
13968
  "!TARGET_64BIT"
13969
  "jmp\t%A0"
13970
  [(set_attr "type" "ibr")
13971
   (set_attr "length_immediate" "0")])
13972
 
13973
(define_insn "*tablejump_1_rtx64"
13974
  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13975
   (use (label_ref (match_operand 1 "" "")))]
13976
  "TARGET_64BIT"
13977
  "jmp\t%A0"
13978
  [(set_attr "type" "ibr")
13979
   (set_attr "length_immediate" "0")])
13980
 
13981
;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13982
 
13983
(define_peephole2
13984
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13985
   (set (match_operand:QI 1 "register_operand" "")
13986
        (match_operator:QI 2 "ix86_comparison_operator"
13987
          [(reg FLAGS_REG) (const_int 0)]))
13988
   (set (match_operand 3 "q_regs_operand" "")
13989
        (zero_extend (match_dup 1)))]
13990
  "(peep2_reg_dead_p (3, operands[1])
13991
    || operands_match_p (operands[1], operands[3]))
13992
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13993
  [(set (match_dup 4) (match_dup 0))
13994
   (set (strict_low_part (match_dup 5))
13995
        (match_dup 2))]
13996
{
13997
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13998
  operands[5] = gen_lowpart (QImode, operands[3]);
13999
  ix86_expand_clear (operands[3]);
14000
})
14001
 
14002
;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14003
 
14004
(define_peephole2
14005
  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14006
   (set (match_operand:QI 1 "register_operand" "")
14007
        (match_operator:QI 2 "ix86_comparison_operator"
14008
          [(reg FLAGS_REG) (const_int 0)]))
14009
   (parallel [(set (match_operand 3 "q_regs_operand" "")
14010
                   (zero_extend (match_dup 1)))
14011
              (clobber (reg:CC FLAGS_REG))])]
14012
  "(peep2_reg_dead_p (3, operands[1])
14013
    || operands_match_p (operands[1], operands[3]))
14014
   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14015
  [(set (match_dup 4) (match_dup 0))
14016
   (set (strict_low_part (match_dup 5))
14017
        (match_dup 2))]
14018
{
14019
  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14020
  operands[5] = gen_lowpart (QImode, operands[3]);
14021
  ix86_expand_clear (operands[3]);
14022
})
14023
 
14024
;; Call instructions.
14025
 
14026
;; The predicates normally associated with named expanders are not properly
14027
;; checked for calls.  This is a bug in the generic code, but it isn't that
14028
;; easy to fix.  Ignore it for now and be prepared to fix things up.
14029
 
14030
;; Call subroutine returning no value.
14031
 
14032
(define_expand "call_pop"
14033
  [(parallel [(call (match_operand:QI 0 "" "")
14034
                    (match_operand:SI 1 "" ""))
14035
              (set (reg:SI SP_REG)
14036
                   (plus:SI (reg:SI SP_REG)
14037
                            (match_operand:SI 3 "" "")))])]
14038
  "!TARGET_64BIT"
14039
{
14040
  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14041
  DONE;
14042
})
14043
 
14044
(define_insn "*call_pop_0"
14045
  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14046
         (match_operand:SI 1 "" ""))
14047
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14048
                            (match_operand:SI 2 "immediate_operand" "")))]
14049
  "!TARGET_64BIT"
14050
{
14051
  if (SIBLING_CALL_P (insn))
14052
    return "jmp\t%P0";
14053
  else
14054
    return "call\t%P0";
14055
}
14056
  [(set_attr "type" "call")])
14057
 
14058
(define_insn "*call_pop_1"
14059
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14060
         (match_operand:SI 1 "" ""))
14061
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14062
                            (match_operand:SI 2 "immediate_operand" "i")))]
14063
  "!TARGET_64BIT"
14064
{
14065
  if (constant_call_address_operand (operands[0], Pmode))
14066
    {
14067
      if (SIBLING_CALL_P (insn))
14068
        return "jmp\t%P0";
14069
      else
14070
        return "call\t%P0";
14071
    }
14072
  if (SIBLING_CALL_P (insn))
14073
    return "jmp\t%A0";
14074
  else
14075
    return "call\t%A0";
14076
}
14077
  [(set_attr "type" "call")])
14078
 
14079
(define_expand "call"
14080
  [(call (match_operand:QI 0 "" "")
14081
         (match_operand 1 "" ""))
14082
   (use (match_operand 2 "" ""))]
14083
  ""
14084
{
14085
  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14086
  DONE;
14087
})
14088
 
14089
(define_expand "sibcall"
14090
  [(call (match_operand:QI 0 "" "")
14091
         (match_operand 1 "" ""))
14092
   (use (match_operand 2 "" ""))]
14093
  ""
14094
{
14095
  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14096
  DONE;
14097
})
14098
 
14099
(define_insn "*call_0"
14100
  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14101
         (match_operand 1 "" ""))]
14102
  ""
14103
{
14104
  if (SIBLING_CALL_P (insn))
14105
    return "jmp\t%P0";
14106
  else
14107
    return "call\t%P0";
14108
}
14109
  [(set_attr "type" "call")])
14110
 
14111
(define_insn "*call_1"
14112
  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14113
         (match_operand 1 "" ""))]
14114
  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14115
{
14116
  if (constant_call_address_operand (operands[0], Pmode))
14117
    return "call\t%P0";
14118
  return "call\t%A0";
14119
}
14120
  [(set_attr "type" "call")])
14121
 
14122
(define_insn "*sibcall_1"
14123
  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14124
         (match_operand 1 "" ""))]
14125
  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14126
{
14127
  if (constant_call_address_operand (operands[0], Pmode))
14128
    return "jmp\t%P0";
14129
  return "jmp\t%A0";
14130
}
14131
  [(set_attr "type" "call")])
14132
 
14133
(define_insn "*call_1_rex64"
14134
  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14135
         (match_operand 1 "" ""))]
14136
  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14137
{
14138
  if (constant_call_address_operand (operands[0], Pmode))
14139
    return "call\t%P0";
14140
  return "call\t%A0";
14141
}
14142
  [(set_attr "type" "call")])
14143
 
14144
(define_insn "*sibcall_1_rex64"
14145
  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14146
         (match_operand 1 "" ""))]
14147
  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14148
  "jmp\t%P0"
14149
  [(set_attr "type" "call")])
14150
 
14151
(define_insn "*sibcall_1_rex64_v"
14152
  [(call (mem:QI (reg:DI 40))
14153
         (match_operand 0 "" ""))]
14154
  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14155
  "jmp\t*%%r11"
14156
  [(set_attr "type" "call")])
14157
 
14158
 
14159
;; Call subroutine, returning value in operand 0
14160
 
14161
(define_expand "call_value_pop"
14162
  [(parallel [(set (match_operand 0 "" "")
14163
                   (call (match_operand:QI 1 "" "")
14164
                         (match_operand:SI 2 "" "")))
14165
              (set (reg:SI SP_REG)
14166
                   (plus:SI (reg:SI SP_REG)
14167
                            (match_operand:SI 4 "" "")))])]
14168
  "!TARGET_64BIT"
14169
{
14170
  ix86_expand_call (operands[0], operands[1], operands[2],
14171
                    operands[3], operands[4], 0);
14172
  DONE;
14173
})
14174
 
14175
(define_expand "call_value"
14176
  [(set (match_operand 0 "" "")
14177
        (call (match_operand:QI 1 "" "")
14178
              (match_operand:SI 2 "" "")))
14179
   (use (match_operand:SI 3 "" ""))]
14180
  ;; Operand 2 not used on the i386.
14181
  ""
14182
{
14183
  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14184
  DONE;
14185
})
14186
 
14187
(define_expand "sibcall_value"
14188
  [(set (match_operand 0 "" "")
14189
        (call (match_operand:QI 1 "" "")
14190
              (match_operand:SI 2 "" "")))
14191
   (use (match_operand:SI 3 "" ""))]
14192
  ;; Operand 2 not used on the i386.
14193
  ""
14194
{
14195
  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14196
  DONE;
14197
})
14198
 
14199
;; Call subroutine returning any type.
14200
 
14201
(define_expand "untyped_call"
14202
  [(parallel [(call (match_operand 0 "" "")
14203
                    (const_int 0))
14204
              (match_operand 1 "" "")
14205
              (match_operand 2 "" "")])]
14206
  ""
14207
{
14208
  int i;
14209
 
14210
  /* In order to give reg-stack an easier job in validating two
14211
     coprocessor registers as containing a possible return value,
14212
     simply pretend the untyped call returns a complex long double
14213
     value.  */
14214
 
14215
  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14216
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14217
                    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14218
                    NULL, 0);
14219
 
14220
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14221
    {
14222
      rtx set = XVECEXP (operands[2], 0, i);
14223
      emit_move_insn (SET_DEST (set), SET_SRC (set));
14224
    }
14225
 
14226
  /* The optimizer does not know that the call sets the function value
14227
     registers we stored in the result block.  We avoid problems by
14228
     claiming that all hard registers are used and clobbered at this
14229
     point.  */
14230
  emit_insn (gen_blockage (const0_rtx));
14231
 
14232
  DONE;
14233
})
14234
 
14235
;; Prologue and epilogue instructions
14236
 
14237
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14238
;; all of memory.  This blocks insns from being moved across this point.
14239
 
14240
(define_insn "blockage"
14241
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14242
  ""
14243
  ""
14244
  [(set_attr "length" "0")])
14245
 
14246
;; Insn emitted into the body of a function to return from a function.
14247
;; This is only done if the function's epilogue is known to be simple.
14248
;; See comments for ix86_can_use_return_insn_p in i386.c.
14249
 
14250
(define_expand "return"
14251
  [(return)]
14252
  "ix86_can_use_return_insn_p ()"
14253
{
14254
  if (current_function_pops_args)
14255
    {
14256
      rtx popc = GEN_INT (current_function_pops_args);
14257
      emit_jump_insn (gen_return_pop_internal (popc));
14258
      DONE;
14259
    }
14260
})
14261
 
14262
(define_insn "return_internal"
14263
  [(return)]
14264
  "reload_completed"
14265
  "ret"
14266
  [(set_attr "length" "1")
14267
   (set_attr "length_immediate" "0")
14268
   (set_attr "modrm" "0")])
14269
 
14270
;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14271
;; instruction Athlon and K8 have.
14272
 
14273
(define_insn "return_internal_long"
14274
  [(return)
14275
   (unspec [(const_int 0)] UNSPEC_REP)]
14276
  "reload_completed"
14277
  "rep {;} ret"
14278
  [(set_attr "length" "1")
14279
   (set_attr "length_immediate" "0")
14280
   (set_attr "prefix_rep" "1")
14281
   (set_attr "modrm" "0")])
14282
 
14283
(define_insn "return_pop_internal"
14284
  [(return)
14285
   (use (match_operand:SI 0 "const_int_operand" ""))]
14286
  "reload_completed"
14287
  "ret\t%0"
14288
  [(set_attr "length" "3")
14289
   (set_attr "length_immediate" "2")
14290
   (set_attr "modrm" "0")])
14291
 
14292
(define_insn "return_indirect_internal"
14293
  [(return)
14294
   (use (match_operand:SI 0 "register_operand" "r"))]
14295
  "reload_completed"
14296
  "jmp\t%A0"
14297
  [(set_attr "type" "ibr")
14298
   (set_attr "length_immediate" "0")])
14299
 
14300
(define_insn "nop"
14301
  [(const_int 0)]
14302
  ""
14303
  "nop"
14304
  [(set_attr "length" "1")
14305
   (set_attr "length_immediate" "0")
14306
   (set_attr "modrm" "0")])
14307
 
14308
;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14309
;; branch prediction penalty for the third jump in a 16-byte
14310
;; block on K8.
14311
 
14312
(define_insn "align"
14313
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14314
  ""
14315
{
14316
#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14317
  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14318
#else
14319
  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14320
     The align insn is used to avoid 3 jump instructions in the row to improve
14321
     branch prediction and the benefits hardly outweigh the cost of extra 8
14322
     nops on the average inserted by full alignment pseudo operation.  */
14323
#endif
14324
  return "";
14325
}
14326
  [(set_attr "length" "16")])
14327
 
14328
(define_expand "prologue"
14329
  [(const_int 1)]
14330
  ""
14331
  "ix86_expand_prologue (); DONE;")
14332
 
14333
(define_insn "set_got"
14334
  [(set (match_operand:SI 0 "register_operand" "=r")
14335
        (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14336
   (clobber (reg:CC FLAGS_REG))]
14337
  "!TARGET_64BIT"
14338
  { return output_set_got (operands[0], NULL_RTX); }
14339
  [(set_attr "type" "multi")
14340
   (set_attr "length" "12")])
14341
 
14342
(define_insn "set_got_labelled"
14343
  [(set (match_operand:SI 0 "register_operand" "=r")
14344
        (unspec:SI [(label_ref (match_operand 1 "" ""))]
14345
         UNSPEC_SET_GOT))
14346
   (clobber (reg:CC FLAGS_REG))]
14347
  "!TARGET_64BIT"
14348
  { return output_set_got (operands[0], operands[1]); }
14349
  [(set_attr "type" "multi")
14350
   (set_attr "length" "12")])
14351
 
14352
(define_insn "set_got_rex64"
14353
  [(set (match_operand:DI 0 "register_operand" "=r")
14354
        (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14355
  "TARGET_64BIT"
14356
  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14357
  [(set_attr "type" "lea")
14358
   (set_attr "length" "6")])
14359
 
14360
(define_expand "epilogue"
14361
  [(const_int 1)]
14362
  ""
14363
  "ix86_expand_epilogue (1); DONE;")
14364
 
14365
(define_expand "sibcall_epilogue"
14366
  [(const_int 1)]
14367
  ""
14368
  "ix86_expand_epilogue (0); DONE;")
14369
 
14370
(define_expand "eh_return"
14371
  [(use (match_operand 0 "register_operand" ""))]
14372
  ""
14373
{
14374
  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14375
 
14376
  /* Tricky bit: we write the address of the handler to which we will
14377
     be returning into someone else's stack frame, one word below the
14378
     stack address we wish to restore.  */
14379
  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14380
  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14381
  tmp = gen_rtx_MEM (Pmode, tmp);
14382
  emit_move_insn (tmp, ra);
14383
 
14384
  if (Pmode == SImode)
14385
    emit_jump_insn (gen_eh_return_si (sa));
14386
  else
14387
    emit_jump_insn (gen_eh_return_di (sa));
14388
  emit_barrier ();
14389
  DONE;
14390
})
14391
 
14392
(define_insn_and_split "eh_return_si"
14393
  [(set (pc)
14394
        (unspec [(match_operand:SI 0 "register_operand" "c")]
14395
                 UNSPEC_EH_RETURN))]
14396
  "!TARGET_64BIT"
14397
  "#"
14398
  "reload_completed"
14399
  [(const_int 1)]
14400
  "ix86_expand_epilogue (2); DONE;")
14401
 
14402
(define_insn_and_split "eh_return_di"
14403
  [(set (pc)
14404
        (unspec [(match_operand:DI 0 "register_operand" "c")]
14405
                 UNSPEC_EH_RETURN))]
14406
  "TARGET_64BIT"
14407
  "#"
14408
  "reload_completed"
14409
  [(const_int 1)]
14410
  "ix86_expand_epilogue (2); DONE;")
14411
 
14412
(define_insn "leave"
14413
  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14414
   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14415
   (clobber (mem:BLK (scratch)))]
14416
  "!TARGET_64BIT"
14417
  "leave"
14418
  [(set_attr "type" "leave")])
14419
 
14420
(define_insn "leave_rex64"
14421
  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14422
   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14423
   (clobber (mem:BLK (scratch)))]
14424
  "TARGET_64BIT"
14425
  "leave"
14426
  [(set_attr "type" "leave")])
14427
 
14428
(define_expand "ffssi2"
14429
  [(parallel
14430
     [(set (match_operand:SI 0 "register_operand" "")
14431
           (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14432
      (clobber (match_scratch:SI 2 ""))
14433
      (clobber (reg:CC FLAGS_REG))])]
14434
  ""
14435
  "")
14436
 
14437
(define_insn_and_split "*ffs_cmove"
14438
  [(set (match_operand:SI 0 "register_operand" "=r")
14439
        (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14440
   (clobber (match_scratch:SI 2 "=&r"))
14441
   (clobber (reg:CC FLAGS_REG))]
14442
  "TARGET_CMOVE"
14443
  "#"
14444
  "&& reload_completed"
14445
  [(set (match_dup 2) (const_int -1))
14446
   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14447
              (set (match_dup 0) (ctz:SI (match_dup 1)))])
14448
   (set (match_dup 0) (if_then_else:SI
14449
                        (eq (reg:CCZ FLAGS_REG) (const_int 0))
14450
                        (match_dup 2)
14451
                        (match_dup 0)))
14452
   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14453
              (clobber (reg:CC FLAGS_REG))])]
14454
  "")
14455
 
14456
(define_insn_and_split "*ffs_no_cmove"
14457
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14458
        (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14459
   (clobber (match_scratch:SI 2 "=&q"))
14460
   (clobber (reg:CC FLAGS_REG))]
14461
  ""
14462
  "#"
14463
  "reload_completed"
14464
  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14465
              (set (match_dup 0) (ctz:SI (match_dup 1)))])
14466
   (set (strict_low_part (match_dup 3))
14467
        (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14468
   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14469
              (clobber (reg:CC FLAGS_REG))])
14470
   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14471
              (clobber (reg:CC FLAGS_REG))])
14472
   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14473
              (clobber (reg:CC FLAGS_REG))])]
14474
{
14475
  operands[3] = gen_lowpart (QImode, operands[2]);
14476
  ix86_expand_clear (operands[2]);
14477
})
14478
 
14479
(define_insn "*ffssi_1"
14480
  [(set (reg:CCZ FLAGS_REG)
14481
        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14482
                     (const_int 0)))
14483
   (set (match_operand:SI 0 "register_operand" "=r")
14484
        (ctz:SI (match_dup 1)))]
14485
  ""
14486
  "bsf{l}\t{%1, %0|%0, %1}"
14487
  [(set_attr "prefix_0f" "1")])
14488
 
14489
(define_expand "ffsdi2"
14490
  [(parallel
14491
     [(set (match_operand:DI 0 "register_operand" "")
14492
           (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14493
      (clobber (match_scratch:DI 2 ""))
14494
      (clobber (reg:CC FLAGS_REG))])]
14495
  "TARGET_64BIT && TARGET_CMOVE"
14496
  "")
14497
 
14498
(define_insn_and_split "*ffs_rex64"
14499
  [(set (match_operand:DI 0 "register_operand" "=r")
14500
        (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14501
   (clobber (match_scratch:DI 2 "=&r"))
14502
   (clobber (reg:CC FLAGS_REG))]
14503
  "TARGET_64BIT && TARGET_CMOVE"
14504
  "#"
14505
  "&& reload_completed"
14506
  [(set (match_dup 2) (const_int -1))
14507
   (parallel [(set (reg:CCZ FLAGS_REG)
14508
                   (compare:CCZ (match_dup 1) (const_int 0)))
14509
              (set (match_dup 0) (ctz:DI (match_dup 1)))])
14510
   (set (match_dup 0) (if_then_else:DI
14511
                        (eq (reg:CCZ FLAGS_REG) (const_int 0))
14512
                        (match_dup 2)
14513
                        (match_dup 0)))
14514
   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14515
              (clobber (reg:CC FLAGS_REG))])]
14516
  "")
14517
 
14518
(define_insn "*ffsdi_1"
14519
  [(set (reg:CCZ FLAGS_REG)
14520
        (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14521
                     (const_int 0)))
14522
   (set (match_operand:DI 0 "register_operand" "=r")
14523
        (ctz:DI (match_dup 1)))]
14524
  "TARGET_64BIT"
14525
  "bsf{q}\t{%1, %0|%0, %1}"
14526
  [(set_attr "prefix_0f" "1")])
14527
 
14528
(define_insn "ctzsi2"
14529
  [(set (match_operand:SI 0 "register_operand" "=r")
14530
        (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14531
   (clobber (reg:CC FLAGS_REG))]
14532
  ""
14533
  "bsf{l}\t{%1, %0|%0, %1}"
14534
  [(set_attr "prefix_0f" "1")])
14535
 
14536
(define_insn "ctzdi2"
14537
  [(set (match_operand:DI 0 "register_operand" "=r")
14538
        (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14539
   (clobber (reg:CC FLAGS_REG))]
14540
  "TARGET_64BIT"
14541
  "bsf{q}\t{%1, %0|%0, %1}"
14542
  [(set_attr "prefix_0f" "1")])
14543
 
14544
(define_expand "clzsi2"
14545
  [(parallel
14546
     [(set (match_operand:SI 0 "register_operand" "")
14547
           (minus:SI (const_int 31)
14548
                     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14549
      (clobber (reg:CC FLAGS_REG))])
14550
   (parallel
14551
     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14552
      (clobber (reg:CC FLAGS_REG))])]
14553
  ""
14554
  "")
14555
 
14556
(define_insn "*bsr"
14557
  [(set (match_operand:SI 0 "register_operand" "=r")
14558
        (minus:SI (const_int 31)
14559
                  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14560
   (clobber (reg:CC FLAGS_REG))]
14561
  ""
14562
  "bsr{l}\t{%1, %0|%0, %1}"
14563
  [(set_attr "prefix_0f" "1")])
14564
 
14565
(define_expand "clzdi2"
14566
  [(parallel
14567
     [(set (match_operand:DI 0 "register_operand" "")
14568
           (minus:DI (const_int 63)
14569
                     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14570
      (clobber (reg:CC FLAGS_REG))])
14571
   (parallel
14572
     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14573
      (clobber (reg:CC FLAGS_REG))])]
14574
  "TARGET_64BIT"
14575
  "")
14576
 
14577
(define_insn "*bsr_rex64"
14578
  [(set (match_operand:DI 0 "register_operand" "=r")
14579
        (minus:DI (const_int 63)
14580
                  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14581
   (clobber (reg:CC FLAGS_REG))]
14582
  "TARGET_64BIT"
14583
  "bsr{q}\t{%1, %0|%0, %1}"
14584
  [(set_attr "prefix_0f" "1")])
14585
 
14586
;; Thread-local storage patterns for ELF.
14587
;;
14588
;; Note that these code sequences must appear exactly as shown
14589
;; in order to allow linker relaxation.
14590
 
14591
(define_insn "*tls_global_dynamic_32_gnu"
14592
  [(set (match_operand:SI 0 "register_operand" "=a")
14593
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14594
                    (match_operand:SI 2 "tls_symbolic_operand" "")
14595
                    (match_operand:SI 3 "call_insn_operand" "")]
14596
                    UNSPEC_TLS_GD))
14597
   (clobber (match_scratch:SI 4 "=d"))
14598
   (clobber (match_scratch:SI 5 "=c"))
14599
   (clobber (reg:CC FLAGS_REG))]
14600
  "!TARGET_64BIT && TARGET_GNU_TLS"
14601
  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14602
  [(set_attr "type" "multi")
14603
   (set_attr "length" "12")])
14604
 
14605
(define_insn "*tls_global_dynamic_32_sun"
14606
  [(set (match_operand:SI 0 "register_operand" "=a")
14607
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14608
                    (match_operand:SI 2 "tls_symbolic_operand" "")
14609
                    (match_operand:SI 3 "call_insn_operand" "")]
14610
                    UNSPEC_TLS_GD))
14611
   (clobber (match_scratch:SI 4 "=d"))
14612
   (clobber (match_scratch:SI 5 "=c"))
14613
   (clobber (reg:CC FLAGS_REG))]
14614
  "!TARGET_64BIT && TARGET_SUN_TLS"
14615
  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14616
        push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14617
  [(set_attr "type" "multi")
14618
   (set_attr "length" "14")])
14619
 
14620
(define_expand "tls_global_dynamic_32"
14621
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14622
                   (unspec:SI
14623
                    [(match_dup 2)
14624
                     (match_operand:SI 1 "tls_symbolic_operand" "")
14625
                     (match_dup 3)]
14626
                    UNSPEC_TLS_GD))
14627
              (clobber (match_scratch:SI 4 ""))
14628
              (clobber (match_scratch:SI 5 ""))
14629
              (clobber (reg:CC FLAGS_REG))])]
14630
  ""
14631
{
14632
  if (flag_pic)
14633
    operands[2] = pic_offset_table_rtx;
14634
  else
14635
    {
14636
      operands[2] = gen_reg_rtx (Pmode);
14637
      emit_insn (gen_set_got (operands[2]));
14638
    }
14639
  if (TARGET_GNU2_TLS)
14640
    {
14641
       emit_insn (gen_tls_dynamic_gnu2_32
14642
                  (operands[0], operands[1], operands[2]));
14643
       DONE;
14644
    }
14645
  operands[3] = ix86_tls_get_addr ();
14646
})
14647
 
14648
(define_insn "*tls_global_dynamic_64"
14649
  [(set (match_operand:DI 0 "register_operand" "=a")
14650
        (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14651
                 (match_operand:DI 3 "" "")))
14652
   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14653
              UNSPEC_TLS_GD)]
14654
  "TARGET_64BIT"
14655
  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14656
  [(set_attr "type" "multi")
14657
   (set_attr "length" "16")])
14658
 
14659
(define_expand "tls_global_dynamic_64"
14660
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14661
                   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14662
              (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14663
                         UNSPEC_TLS_GD)])]
14664
  ""
14665
{
14666
  if (TARGET_GNU2_TLS)
14667
    {
14668
       emit_insn (gen_tls_dynamic_gnu2_64
14669
                  (operands[0], operands[1]));
14670
       DONE;
14671
    }
14672
  operands[2] = ix86_tls_get_addr ();
14673
})
14674
 
14675
(define_insn "*tls_local_dynamic_base_32_gnu"
14676
  [(set (match_operand:SI 0 "register_operand" "=a")
14677
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14678
                    (match_operand:SI 2 "call_insn_operand" "")]
14679
                   UNSPEC_TLS_LD_BASE))
14680
   (clobber (match_scratch:SI 3 "=d"))
14681
   (clobber (match_scratch:SI 4 "=c"))
14682
   (clobber (reg:CC FLAGS_REG))]
14683
  "!TARGET_64BIT && TARGET_GNU_TLS"
14684
  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14685
  [(set_attr "type" "multi")
14686
   (set_attr "length" "11")])
14687
 
14688
(define_insn "*tls_local_dynamic_base_32_sun"
14689
  [(set (match_operand:SI 0 "register_operand" "=a")
14690
        (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14691
                    (match_operand:SI 2 "call_insn_operand" "")]
14692
                   UNSPEC_TLS_LD_BASE))
14693
   (clobber (match_scratch:SI 3 "=d"))
14694
   (clobber (match_scratch:SI 4 "=c"))
14695
   (clobber (reg:CC FLAGS_REG))]
14696
  "!TARGET_64BIT && TARGET_SUN_TLS"
14697
  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14698
        push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14699
  [(set_attr "type" "multi")
14700
   (set_attr "length" "13")])
14701
 
14702
(define_expand "tls_local_dynamic_base_32"
14703
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14704
                   (unspec:SI [(match_dup 1) (match_dup 2)]
14705
                              UNSPEC_TLS_LD_BASE))
14706
              (clobber (match_scratch:SI 3 ""))
14707
              (clobber (match_scratch:SI 4 ""))
14708
              (clobber (reg:CC FLAGS_REG))])]
14709
  ""
14710
{
14711
  if (flag_pic)
14712
    operands[1] = pic_offset_table_rtx;
14713
  else
14714
    {
14715
      operands[1] = gen_reg_rtx (Pmode);
14716
      emit_insn (gen_set_got (operands[1]));
14717
    }
14718
  if (TARGET_GNU2_TLS)
14719
    {
14720
       emit_insn (gen_tls_dynamic_gnu2_32
14721
                  (operands[0], ix86_tls_module_base (), operands[1]));
14722
       DONE;
14723
    }
14724
  operands[2] = ix86_tls_get_addr ();
14725
})
14726
 
14727
(define_insn "*tls_local_dynamic_base_64"
14728
  [(set (match_operand:DI 0 "register_operand" "=a")
14729
        (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14730
                 (match_operand:DI 2 "" "")))
14731
   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14732
  "TARGET_64BIT"
14733
  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14734
  [(set_attr "type" "multi")
14735
   (set_attr "length" "12")])
14736
 
14737
(define_expand "tls_local_dynamic_base_64"
14738
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14739
                   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14740
              (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14741
  ""
14742
{
14743
  if (TARGET_GNU2_TLS)
14744
    {
14745
       emit_insn (gen_tls_dynamic_gnu2_64
14746
                  (operands[0], ix86_tls_module_base ()));
14747
       DONE;
14748
    }
14749
  operands[1] = ix86_tls_get_addr ();
14750
})
14751
 
14752
;; Local dynamic of a single variable is a lose.  Show combine how
14753
;; to convert that back to global dynamic.
14754
 
14755
(define_insn_and_split "*tls_local_dynamic_32_once"
14756
  [(set (match_operand:SI 0 "register_operand" "=a")
14757
        (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14758
                             (match_operand:SI 2 "call_insn_operand" "")]
14759
                            UNSPEC_TLS_LD_BASE)
14760
                 (const:SI (unspec:SI
14761
                            [(match_operand:SI 3 "tls_symbolic_operand" "")]
14762
                            UNSPEC_DTPOFF))))
14763
   (clobber (match_scratch:SI 4 "=d"))
14764
   (clobber (match_scratch:SI 5 "=c"))
14765
   (clobber (reg:CC FLAGS_REG))]
14766
  ""
14767
  "#"
14768
  ""
14769
  [(parallel [(set (match_dup 0)
14770
                   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14771
                              UNSPEC_TLS_GD))
14772
              (clobber (match_dup 4))
14773
              (clobber (match_dup 5))
14774
              (clobber (reg:CC FLAGS_REG))])]
14775
  "")
14776
 
14777
;; Load and add the thread base pointer from %gs:0.
14778
 
14779
(define_insn "*load_tp_si"
14780
  [(set (match_operand:SI 0 "register_operand" "=r")
14781
        (unspec:SI [(const_int 0)] UNSPEC_TP))]
14782
  "!TARGET_64BIT"
14783
  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14784
  [(set_attr "type" "imov")
14785
   (set_attr "modrm" "0")
14786
   (set_attr "length" "7")
14787
   (set_attr "memory" "load")
14788
   (set_attr "imm_disp" "false")])
14789
 
14790
(define_insn "*add_tp_si"
14791
  [(set (match_operand:SI 0 "register_operand" "=r")
14792
        (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14793
                 (match_operand:SI 1 "register_operand" "0")))
14794
   (clobber (reg:CC FLAGS_REG))]
14795
  "!TARGET_64BIT"
14796
  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14797
  [(set_attr "type" "alu")
14798
   (set_attr "modrm" "0")
14799
   (set_attr "length" "7")
14800
   (set_attr "memory" "load")
14801
   (set_attr "imm_disp" "false")])
14802
 
14803
(define_insn "*load_tp_di"
14804
  [(set (match_operand:DI 0 "register_operand" "=r")
14805
        (unspec:DI [(const_int 0)] UNSPEC_TP))]
14806
  "TARGET_64BIT"
14807
  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14808
  [(set_attr "type" "imov")
14809
   (set_attr "modrm" "0")
14810
   (set_attr "length" "7")
14811
   (set_attr "memory" "load")
14812
   (set_attr "imm_disp" "false")])
14813
 
14814
(define_insn "*add_tp_di"
14815
  [(set (match_operand:DI 0 "register_operand" "=r")
14816
        (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14817
                 (match_operand:DI 1 "register_operand" "0")))
14818
   (clobber (reg:CC FLAGS_REG))]
14819
  "TARGET_64BIT"
14820
  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14821
  [(set_attr "type" "alu")
14822
   (set_attr "modrm" "0")
14823
   (set_attr "length" "7")
14824
   (set_attr "memory" "load")
14825
   (set_attr "imm_disp" "false")])
14826
 
14827
;; GNU2 TLS patterns can be split.
14828
 
14829
(define_expand "tls_dynamic_gnu2_32"
14830
  [(set (match_dup 3)
14831
        (plus:SI (match_operand:SI 2 "register_operand" "")
14832
                 (const:SI
14833
                  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14834
                             UNSPEC_TLSDESC))))
14835
   (parallel
14836
    [(set (match_operand:SI 0 "register_operand" "")
14837
          (unspec:SI [(match_dup 1) (match_dup 3)
14838
                      (match_dup 2) (reg:SI SP_REG)]
14839
                      UNSPEC_TLSDESC))
14840
     (clobber (reg:CC FLAGS_REG))])]
14841
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14842
{
14843
  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14844
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14845
})
14846
 
14847
(define_insn "*tls_dynamic_lea_32"
14848
  [(set (match_operand:SI 0 "register_operand" "=r")
14849
        (plus:SI (match_operand:SI 1 "register_operand" "b")
14850
                 (const:SI
14851
                  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14852
                              UNSPEC_TLSDESC))))]
14853
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14854
  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14855
  [(set_attr "type" "lea")
14856
   (set_attr "mode" "SI")
14857
   (set_attr "length" "6")
14858
   (set_attr "length_address" "4")])
14859
 
14860
(define_insn "*tls_dynamic_call_32"
14861
  [(set (match_operand:SI 0 "register_operand" "=a")
14862
        (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14863
                    (match_operand:SI 2 "register_operand" "0")
14864
                    ;; we have to make sure %ebx still points to the GOT
14865
                    (match_operand:SI 3 "register_operand" "b")
14866
                    (reg:SI SP_REG)]
14867
                   UNSPEC_TLSDESC))
14868
   (clobber (reg:CC FLAGS_REG))]
14869
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14870
  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14871
  [(set_attr "type" "call")
14872
   (set_attr "length" "2")
14873
   (set_attr "length_address" "0")])
14874
 
14875
(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14876
  [(set (match_operand:SI 0 "register_operand" "=&a")
14877
        (plus:SI
14878
         (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14879
                     (match_operand:SI 4 "" "")
14880
                     (match_operand:SI 2 "register_operand" "b")
14881
                     (reg:SI SP_REG)]
14882
                    UNSPEC_TLSDESC)
14883
         (const:SI (unspec:SI
14884
                    [(match_operand:SI 1 "tls_symbolic_operand" "")]
14885
                    UNSPEC_DTPOFF))))
14886
   (clobber (reg:CC FLAGS_REG))]
14887
  "!TARGET_64BIT && TARGET_GNU2_TLS"
14888
  "#"
14889
  ""
14890
  [(set (match_dup 0) (match_dup 5))]
14891
{
14892
  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14893
  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14894
})
14895
 
14896
(define_expand "tls_dynamic_gnu2_64"
14897
  [(set (match_dup 2)
14898
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14899
                   UNSPEC_TLSDESC))
14900
   (parallel
14901
    [(set (match_operand:DI 0 "register_operand" "")
14902
          (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14903
                     UNSPEC_TLSDESC))
14904
     (clobber (reg:CC FLAGS_REG))])]
14905
  "TARGET_64BIT && TARGET_GNU2_TLS"
14906
{
14907
  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14908
  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14909
})
14910
 
14911
(define_insn "*tls_dynamic_lea_64"
14912
  [(set (match_operand:DI 0 "register_operand" "=r")
14913
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14914
                   UNSPEC_TLSDESC))]
14915
  "TARGET_64BIT && TARGET_GNU2_TLS"
14916
  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14917
  [(set_attr "type" "lea")
14918
   (set_attr "mode" "DI")
14919
   (set_attr "length" "7")
14920
   (set_attr "length_address" "4")])
14921
 
14922
(define_insn "*tls_dynamic_call_64"
14923
  [(set (match_operand:DI 0 "register_operand" "=a")
14924
        (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14925
                    (match_operand:DI 2 "register_operand" "0")
14926
                    (reg:DI SP_REG)]
14927
                   UNSPEC_TLSDESC))
14928
   (clobber (reg:CC FLAGS_REG))]
14929
  "TARGET_64BIT && TARGET_GNU2_TLS"
14930
  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14931
  [(set_attr "type" "call")
14932
   (set_attr "length" "2")
14933
   (set_attr "length_address" "0")])
14934
 
14935
(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14936
  [(set (match_operand:DI 0 "register_operand" "=&a")
14937
        (plus:DI
14938
         (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14939
                     (match_operand:DI 3 "" "")
14940
                     (reg:DI SP_REG)]
14941
                    UNSPEC_TLSDESC)
14942
         (const:DI (unspec:DI
14943
                    [(match_operand:DI 1 "tls_symbolic_operand" "")]
14944
                    UNSPEC_DTPOFF))))
14945
   (clobber (reg:CC FLAGS_REG))]
14946
  "TARGET_64BIT && TARGET_GNU2_TLS"
14947
  "#"
14948
  ""
14949
  [(set (match_dup 0) (match_dup 4))]
14950
{
14951
  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14952
  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14953
})
14954
 
14955
;;
14956
 
14957
;; These patterns match the binary 387 instructions for addM3, subM3,
14958
;; mulM3 and divM3.  There are three patterns for each of DFmode and
14959
;; SFmode.  The first is the normal insn, the second the same insn but
14960
;; with one operand a conversion, and the third the same insn but with
14961
;; the other operand a conversion.  The conversion may be SFmode or
14962
;; SImode if the target mode DFmode, but only SImode if the target mode
14963
;; is SFmode.
14964
 
14965
;; Gcc is slightly more smart about handling normal two address instructions
14966
;; so use special patterns for add and mull.
14967
 
14968
(define_insn "*fop_sf_comm_mixed"
14969
  [(set (match_operand:SF 0 "register_operand" "=f,x")
14970
        (match_operator:SF 3 "binary_fp_operator"
14971
                        [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14972
                         (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14973
  "TARGET_MIX_SSE_I387
14974
   && COMMUTATIVE_ARITH_P (operands[3])
14975
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14976
  "* return output_387_binary_op (insn, operands);"
14977
  [(set (attr "type")
14978
        (if_then_else (eq_attr "alternative" "1")
14979
           (if_then_else (match_operand:SF 3 "mult_operator" "")
14980
              (const_string "ssemul")
14981
              (const_string "sseadd"))
14982
           (if_then_else (match_operand:SF 3 "mult_operator" "")
14983
              (const_string "fmul")
14984
              (const_string "fop"))))
14985
   (set_attr "mode" "SF")])
14986
 
14987
(define_insn "*fop_sf_comm_sse"
14988
  [(set (match_operand:SF 0 "register_operand" "=x")
14989
        (match_operator:SF 3 "binary_fp_operator"
14990
                        [(match_operand:SF 1 "nonimmediate_operand" "%0")
14991
                         (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14992
  "TARGET_SSE_MATH
14993
   && COMMUTATIVE_ARITH_P (operands[3])
14994
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14995
  "* return output_387_binary_op (insn, operands);"
14996
  [(set (attr "type")
14997
        (if_then_else (match_operand:SF 3 "mult_operator" "")
14998
           (const_string "ssemul")
14999
           (const_string "sseadd")))
15000
   (set_attr "mode" "SF")])
15001
 
15002
(define_insn "*fop_sf_comm_i387"
15003
  [(set (match_operand:SF 0 "register_operand" "=f")
15004
        (match_operator:SF 3 "binary_fp_operator"
15005
                        [(match_operand:SF 1 "nonimmediate_operand" "%0")
15006
                         (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15007
  "TARGET_80387
15008
   && COMMUTATIVE_ARITH_P (operands[3])
15009
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15010
  "* return output_387_binary_op (insn, operands);"
15011
  [(set (attr "type")
15012
        (if_then_else (match_operand:SF 3 "mult_operator" "")
15013
           (const_string "fmul")
15014
           (const_string "fop")))
15015
   (set_attr "mode" "SF")])
15016
 
15017
(define_insn "*fop_sf_1_mixed"
15018
  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15019
        (match_operator:SF 3 "binary_fp_operator"
15020
                        [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15021
                         (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15022
  "TARGET_MIX_SSE_I387
15023
   && !COMMUTATIVE_ARITH_P (operands[3])
15024
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15025
  "* return output_387_binary_op (insn, operands);"
15026
  [(set (attr "type")
15027
        (cond [(and (eq_attr "alternative" "2")
15028
                    (match_operand:SF 3 "mult_operator" ""))
15029
                 (const_string "ssemul")
15030
               (and (eq_attr "alternative" "2")
15031
                    (match_operand:SF 3 "div_operator" ""))
15032
                 (const_string "ssediv")
15033
               (eq_attr "alternative" "2")
15034
                 (const_string "sseadd")
15035
               (match_operand:SF 3 "mult_operator" "")
15036
                 (const_string "fmul")
15037
               (match_operand:SF 3 "div_operator" "")
15038
                 (const_string "fdiv")
15039
              ]
15040
              (const_string "fop")))
15041
   (set_attr "mode" "SF")])
15042
 
15043
(define_insn "*fop_sf_1_sse"
15044
  [(set (match_operand:SF 0 "register_operand" "=x")
15045
        (match_operator:SF 3 "binary_fp_operator"
15046
                        [(match_operand:SF 1 "register_operand" "0")
15047
                         (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15048
  "TARGET_SSE_MATH
15049
   && !COMMUTATIVE_ARITH_P (operands[3])"
15050
  "* return output_387_binary_op (insn, operands);"
15051
  [(set (attr "type")
15052
        (cond [(match_operand:SF 3 "mult_operator" "")
15053
                 (const_string "ssemul")
15054
               (match_operand:SF 3 "div_operator" "")
15055
                 (const_string "ssediv")
15056
              ]
15057
              (const_string "sseadd")))
15058
   (set_attr "mode" "SF")])
15059
 
15060
;; This pattern is not fully shadowed by the pattern above.
15061
(define_insn "*fop_sf_1_i387"
15062
  [(set (match_operand:SF 0 "register_operand" "=f,f")
15063
        (match_operator:SF 3 "binary_fp_operator"
15064
                        [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15065
                         (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15066
  "TARGET_80387 && !TARGET_SSE_MATH
15067
   && !COMMUTATIVE_ARITH_P (operands[3])
15068
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15069
  "* return output_387_binary_op (insn, operands);"
15070
  [(set (attr "type")
15071
        (cond [(match_operand:SF 3 "mult_operator" "")
15072
                 (const_string "fmul")
15073
               (match_operand:SF 3 "div_operator" "")
15074
                 (const_string "fdiv")
15075
              ]
15076
              (const_string "fop")))
15077
   (set_attr "mode" "SF")])
15078
 
15079
;; ??? Add SSE splitters for these!
15080
(define_insn "*fop_sf_2_i387"
15081
  [(set (match_operand:SF 0 "register_operand" "=f,f")
15082
        (match_operator:SF 3 "binary_fp_operator"
15083
          [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15084
           (match_operand:SF 2 "register_operand" "0,0")]))]
15085
  "TARGET_80387 && TARGET_USE_MODE_FIOP && !TARGET_SSE_MATH"
15086
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15087
  [(set (attr "type")
15088
        (cond [(match_operand:SF 3 "mult_operator" "")
15089
                 (const_string "fmul")
15090
               (match_operand:SF 3 "div_operator" "")
15091
                 (const_string "fdiv")
15092
              ]
15093
              (const_string "fop")))
15094
   (set_attr "fp_int_src" "true")
15095
   (set_attr "mode" "")])
15096
 
15097
(define_insn "*fop_sf_3_i387"
15098
  [(set (match_operand:SF 0 "register_operand" "=f,f")
15099
        (match_operator:SF 3 "binary_fp_operator"
15100
          [(match_operand:SF 1 "register_operand" "0,0")
15101
           (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15102
  "TARGET_80387 && TARGET_USE_MODE_FIOP && !TARGET_SSE_MATH"
15103
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15104
  [(set (attr "type")
15105
        (cond [(match_operand:SF 3 "mult_operator" "")
15106
                 (const_string "fmul")
15107
               (match_operand:SF 3 "div_operator" "")
15108
                 (const_string "fdiv")
15109
              ]
15110
              (const_string "fop")))
15111
   (set_attr "fp_int_src" "true")
15112
   (set_attr "mode" "")])
15113
 
15114
(define_insn "*fop_df_comm_mixed"
15115
  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15116
        (match_operator:DF 3 "binary_fp_operator"
15117
                        [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15118
                         (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15119
  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15120
   && COMMUTATIVE_ARITH_P (operands[3])
15121
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15122
  "* return output_387_binary_op (insn, operands);"
15123
  [(set (attr "type")
15124
        (if_then_else (eq_attr "alternative" "1")
15125
           (if_then_else (match_operand:DF 3 "mult_operator" "")
15126
              (const_string "ssemul")
15127
              (const_string "sseadd"))
15128
           (if_then_else (match_operand:DF 3 "mult_operator" "")
15129
              (const_string "fmul")
15130
              (const_string "fop"))))
15131
   (set_attr "mode" "DF")])
15132
 
15133
(define_insn "*fop_df_comm_sse"
15134
  [(set (match_operand:DF 0 "register_operand" "=Y")
15135
        (match_operator:DF 3 "binary_fp_operator"
15136
                        [(match_operand:DF 1 "nonimmediate_operand" "%0")
15137
                         (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15138
  "TARGET_SSE2 && TARGET_SSE_MATH
15139
   && COMMUTATIVE_ARITH_P (operands[3])
15140
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15141
  "* return output_387_binary_op (insn, operands);"
15142
  [(set (attr "type")
15143
        (if_then_else (match_operand:DF 3 "mult_operator" "")
15144
           (const_string "ssemul")
15145
           (const_string "sseadd")))
15146
   (set_attr "mode" "DF")])
15147
 
15148
(define_insn "*fop_df_comm_i387"
15149
  [(set (match_operand:DF 0 "register_operand" "=f")
15150
        (match_operator:DF 3 "binary_fp_operator"
15151
                        [(match_operand:DF 1 "nonimmediate_operand" "%0")
15152
                         (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15153
  "TARGET_80387
15154
   && COMMUTATIVE_ARITH_P (operands[3])
15155
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15156
  "* return output_387_binary_op (insn, operands);"
15157
  [(set (attr "type")
15158
        (if_then_else (match_operand:DF 3 "mult_operator" "")
15159
           (const_string "fmul")
15160
           (const_string "fop")))
15161
   (set_attr "mode" "DF")])
15162
 
15163
(define_insn "*fop_df_1_mixed"
15164
  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15165
        (match_operator:DF 3 "binary_fp_operator"
15166
                        [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15167
                         (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15168
  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15169
   && !COMMUTATIVE_ARITH_P (operands[3])
15170
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15171
  "* return output_387_binary_op (insn, operands);"
15172
  [(set (attr "type")
15173
        (cond [(and (eq_attr "alternative" "2")
15174
                    (match_operand:DF 3 "mult_operator" ""))
15175
                 (const_string "ssemul")
15176
               (and (eq_attr "alternative" "2")
15177
                    (match_operand:DF 3 "div_operator" ""))
15178
                 (const_string "ssediv")
15179
               (eq_attr "alternative" "2")
15180
                 (const_string "sseadd")
15181
               (match_operand:DF 3 "mult_operator" "")
15182
                 (const_string "fmul")
15183
               (match_operand:DF 3 "div_operator" "")
15184
                 (const_string "fdiv")
15185
              ]
15186
              (const_string "fop")))
15187
   (set_attr "mode" "DF")])
15188
 
15189
(define_insn "*fop_df_1_sse"
15190
  [(set (match_operand:DF 0 "register_operand" "=Y")
15191
        (match_operator:DF 3 "binary_fp_operator"
15192
                        [(match_operand:DF 1 "register_operand" "0")
15193
                         (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15194
  "TARGET_SSE2 && TARGET_SSE_MATH
15195
   && !COMMUTATIVE_ARITH_P (operands[3])"
15196
  "* return output_387_binary_op (insn, operands);"
15197
  [(set_attr "mode" "DF")
15198
   (set (attr "type")
15199
        (cond [(match_operand:DF 3 "mult_operator" "")
15200
                 (const_string "ssemul")
15201
               (match_operand:DF 3 "div_operator" "")
15202
                 (const_string "ssediv")
15203
              ]
15204
              (const_string "sseadd")))])
15205
 
15206
;; This pattern is not fully shadowed by the pattern above.
15207
(define_insn "*fop_df_1_i387"
15208
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15209
        (match_operator:DF 3 "binary_fp_operator"
15210
                        [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15211
                         (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15212
  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15213
   && !COMMUTATIVE_ARITH_P (operands[3])
15214
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15215
  "* return output_387_binary_op (insn, operands);"
15216
  [(set (attr "type")
15217
        (cond [(match_operand:DF 3 "mult_operator" "")
15218
                 (const_string "fmul")
15219
               (match_operand:DF 3 "div_operator" "")
15220
                 (const_string "fdiv")
15221
              ]
15222
              (const_string "fop")))
15223
   (set_attr "mode" "DF")])
15224
 
15225
;; ??? Add SSE splitters for these!
15226
(define_insn "*fop_df_2_i387"
15227
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15228
        (match_operator:DF 3 "binary_fp_operator"
15229
           [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15230
            (match_operand:DF 2 "register_operand" "0,0")]))]
15231
  "TARGET_80387 && TARGET_USE_MODE_FIOP
15232
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15233
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15234
  [(set (attr "type")
15235
        (cond [(match_operand:DF 3 "mult_operator" "")
15236
                 (const_string "fmul")
15237
               (match_operand:DF 3 "div_operator" "")
15238
                 (const_string "fdiv")
15239
              ]
15240
              (const_string "fop")))
15241
   (set_attr "fp_int_src" "true")
15242
   (set_attr "mode" "")])
15243
 
15244
(define_insn "*fop_df_3_i387"
15245
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15246
        (match_operator:DF 3 "binary_fp_operator"
15247
           [(match_operand:DF 1 "register_operand" "0,0")
15248
            (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15249
  "TARGET_80387 && TARGET_USE_MODE_FIOP
15250
   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15251
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15252
  [(set (attr "type")
15253
        (cond [(match_operand:DF 3 "mult_operator" "")
15254
                 (const_string "fmul")
15255
               (match_operand:DF 3 "div_operator" "")
15256
                 (const_string "fdiv")
15257
              ]
15258
              (const_string "fop")))
15259
   (set_attr "fp_int_src" "true")
15260
   (set_attr "mode" "")])
15261
 
15262
(define_insn "*fop_df_4_i387"
15263
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15264
        (match_operator:DF 3 "binary_fp_operator"
15265
           [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15266
            (match_operand:DF 2 "register_operand" "0,f")]))]
15267
  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15268
   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15269
  "* return output_387_binary_op (insn, operands);"
15270
  [(set (attr "type")
15271
        (cond [(match_operand:DF 3 "mult_operator" "")
15272
                 (const_string "fmul")
15273
               (match_operand:DF 3 "div_operator" "")
15274
                 (const_string "fdiv")
15275
              ]
15276
              (const_string "fop")))
15277
   (set_attr "mode" "SF")])
15278
 
15279
(define_insn "*fop_df_5_i387"
15280
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15281
        (match_operator:DF 3 "binary_fp_operator"
15282
          [(match_operand:DF 1 "register_operand" "0,f")
15283
           (float_extend:DF
15284
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15285
  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15286
  "* return output_387_binary_op (insn, operands);"
15287
  [(set (attr "type")
15288
        (cond [(match_operand:DF 3 "mult_operator" "")
15289
                 (const_string "fmul")
15290
               (match_operand:DF 3 "div_operator" "")
15291
                 (const_string "fdiv")
15292
              ]
15293
              (const_string "fop")))
15294
   (set_attr "mode" "SF")])
15295
 
15296
(define_insn "*fop_df_6_i387"
15297
  [(set (match_operand:DF 0 "register_operand" "=f,f")
15298
        (match_operator:DF 3 "binary_fp_operator"
15299
          [(float_extend:DF
15300
            (match_operand:SF 1 "register_operand" "0,f"))
15301
           (float_extend:DF
15302
            (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15303
  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15304
  "* return output_387_binary_op (insn, operands);"
15305
  [(set (attr "type")
15306
        (cond [(match_operand:DF 3 "mult_operator" "")
15307
                 (const_string "fmul")
15308
               (match_operand:DF 3 "div_operator" "")
15309
                 (const_string "fdiv")
15310
              ]
15311
              (const_string "fop")))
15312
   (set_attr "mode" "SF")])
15313
 
15314
(define_insn "*fop_xf_comm_i387"
15315
  [(set (match_operand:XF 0 "register_operand" "=f")
15316
        (match_operator:XF 3 "binary_fp_operator"
15317
                        [(match_operand:XF 1 "register_operand" "%0")
15318
                         (match_operand:XF 2 "register_operand" "f")]))]
15319
  "TARGET_80387
15320
   && COMMUTATIVE_ARITH_P (operands[3])"
15321
  "* return output_387_binary_op (insn, operands);"
15322
  [(set (attr "type")
15323
        (if_then_else (match_operand:XF 3 "mult_operator" "")
15324
           (const_string "fmul")
15325
           (const_string "fop")))
15326
   (set_attr "mode" "XF")])
15327
 
15328
(define_insn "*fop_xf_1_i387"
15329
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15330
        (match_operator:XF 3 "binary_fp_operator"
15331
                        [(match_operand:XF 1 "register_operand" "0,f")
15332
                         (match_operand:XF 2 "register_operand" "f,0")]))]
15333
  "TARGET_80387
15334
   && !COMMUTATIVE_ARITH_P (operands[3])"
15335
  "* return output_387_binary_op (insn, operands);"
15336
  [(set (attr "type")
15337
        (cond [(match_operand:XF 3 "mult_operator" "")
15338
                 (const_string "fmul")
15339
               (match_operand:XF 3 "div_operator" "")
15340
                 (const_string "fdiv")
15341
              ]
15342
              (const_string "fop")))
15343
   (set_attr "mode" "XF")])
15344
 
15345
(define_insn "*fop_xf_2_i387"
15346
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15347
        (match_operator:XF 3 "binary_fp_operator"
15348
           [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15349
            (match_operand:XF 2 "register_operand" "0,0")]))]
15350
  "TARGET_80387 && TARGET_USE_MODE_FIOP"
15351
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15352
  [(set (attr "type")
15353
        (cond [(match_operand:XF 3 "mult_operator" "")
15354
                 (const_string "fmul")
15355
               (match_operand:XF 3 "div_operator" "")
15356
                 (const_string "fdiv")
15357
              ]
15358
              (const_string "fop")))
15359
   (set_attr "fp_int_src" "true")
15360
   (set_attr "mode" "")])
15361
 
15362
(define_insn "*fop_xf_3_i387"
15363
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15364
        (match_operator:XF 3 "binary_fp_operator"
15365
          [(match_operand:XF 1 "register_operand" "0,0")
15366
           (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15367
  "TARGET_80387 && TARGET_USE_MODE_FIOP"
15368
  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15369
  [(set (attr "type")
15370
        (cond [(match_operand:XF 3 "mult_operator" "")
15371
                 (const_string "fmul")
15372
               (match_operand:XF 3 "div_operator" "")
15373
                 (const_string "fdiv")
15374
              ]
15375
              (const_string "fop")))
15376
   (set_attr "fp_int_src" "true")
15377
   (set_attr "mode" "")])
15378
 
15379
(define_insn "*fop_xf_4_i387"
15380
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15381
        (match_operator:XF 3 "binary_fp_operator"
15382
           [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15383
            (match_operand:XF 2 "register_operand" "0,f")]))]
15384
  "TARGET_80387"
15385
  "* return output_387_binary_op (insn, operands);"
15386
  [(set (attr "type")
15387
        (cond [(match_operand:XF 3 "mult_operator" "")
15388
                 (const_string "fmul")
15389
               (match_operand:XF 3 "div_operator" "")
15390
                 (const_string "fdiv")
15391
              ]
15392
              (const_string "fop")))
15393
   (set_attr "mode" "SF")])
15394
 
15395
(define_insn "*fop_xf_5_i387"
15396
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15397
        (match_operator:XF 3 "binary_fp_operator"
15398
          [(match_operand:XF 1 "register_operand" "0,f")
15399
           (float_extend:XF
15400
            (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15401
  "TARGET_80387"
15402
  "* return output_387_binary_op (insn, operands);"
15403
  [(set (attr "type")
15404
        (cond [(match_operand:XF 3 "mult_operator" "")
15405
                 (const_string "fmul")
15406
               (match_operand:XF 3 "div_operator" "")
15407
                 (const_string "fdiv")
15408
              ]
15409
              (const_string "fop")))
15410
   (set_attr "mode" "SF")])
15411
 
15412
(define_insn "*fop_xf_6_i387"
15413
  [(set (match_operand:XF 0 "register_operand" "=f,f")
15414
        (match_operator:XF 3 "binary_fp_operator"
15415
          [(float_extend:XF
15416
            (match_operand 1 "register_operand" "0,f"))
15417
           (float_extend:XF
15418
            (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15419
  "TARGET_80387"
15420
  "* return output_387_binary_op (insn, operands);"
15421
  [(set (attr "type")
15422
        (cond [(match_operand:XF 3 "mult_operator" "")
15423
                 (const_string "fmul")
15424
               (match_operand:XF 3 "div_operator" "")
15425
                 (const_string "fdiv")
15426
              ]
15427
              (const_string "fop")))
15428
   (set_attr "mode" "SF")])
15429
 
15430
(define_split
15431
  [(set (match_operand 0 "register_operand" "")
15432
        (match_operator 3 "binary_fp_operator"
15433
           [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15434
            (match_operand 2 "register_operand" "")]))]
15435
  "TARGET_80387 && reload_completed
15436
   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15437
  [(const_int 0)]
15438
{
15439
  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15440
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15441
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15442
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
15443
                                          GET_MODE (operands[3]),
15444
                                          operands[4],
15445
                                          operands[2])));
15446
  ix86_free_from_memory (GET_MODE (operands[1]));
15447
  DONE;
15448
})
15449
 
15450
(define_split
15451
  [(set (match_operand 0 "register_operand" "")
15452
        (match_operator 3 "binary_fp_operator"
15453
           [(match_operand 1 "register_operand" "")
15454
            (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15455
  "TARGET_80387 && reload_completed
15456
   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15457
  [(const_int 0)]
15458
{
15459
  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15460
  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15461
  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15462
                          gen_rtx_fmt_ee (GET_CODE (operands[3]),
15463
                                          GET_MODE (operands[3]),
15464
                                          operands[1],
15465
                                          operands[4])));
15466
  ix86_free_from_memory (GET_MODE (operands[2]));
15467
  DONE;
15468
})
15469
 
15470
;; FPU special functions.
15471
 
15472
(define_expand "sqrtsf2"
15473
  [(set (match_operand:SF 0 "register_operand" "")
15474
        (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15475
  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15476
{
15477
  if (!TARGET_SSE_MATH)
15478
    operands[1] = force_reg (SFmode, operands[1]);
15479
})
15480
 
15481
(define_insn "*sqrtsf2_mixed"
15482
  [(set (match_operand:SF 0 "register_operand" "=f,x")
15483
        (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15484
  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15485
  "@
15486
   fsqrt
15487
   sqrtss\t{%1, %0|%0, %1}"
15488
  [(set_attr "type" "fpspc,sse")
15489
   (set_attr "mode" "SF,SF")
15490
   (set_attr "athlon_decode" "direct,*")])
15491
 
15492
(define_insn "*sqrtsf2_sse"
15493
  [(set (match_operand:SF 0 "register_operand" "=x")
15494
        (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15495
  "TARGET_SSE_MATH"
15496
  "sqrtss\t{%1, %0|%0, %1}"
15497
  [(set_attr "type" "sse")
15498
   (set_attr "mode" "SF")
15499
   (set_attr "athlon_decode" "*")])
15500
 
15501
(define_insn "*sqrtsf2_i387"
15502
  [(set (match_operand:SF 0 "register_operand" "=f")
15503
        (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15504
  "TARGET_USE_FANCY_MATH_387"
15505
  "fsqrt"
15506
  [(set_attr "type" "fpspc")
15507
   (set_attr "mode" "SF")
15508
   (set_attr "athlon_decode" "direct")])
15509
 
15510
(define_expand "sqrtdf2"
15511
  [(set (match_operand:DF 0 "register_operand" "")
15512
        (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15513
  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15514
{
15515
  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15516
    operands[1] = force_reg (DFmode, operands[1]);
15517
})
15518
 
15519
(define_insn "*sqrtdf2_mixed"
15520
  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15521
        (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15522
  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15523
  "@
15524
   fsqrt
15525
   sqrtsd\t{%1, %0|%0, %1}"
15526
  [(set_attr "type" "fpspc,sse")
15527
   (set_attr "mode" "DF,DF")
15528
   (set_attr "athlon_decode" "direct,*")])
15529
 
15530
(define_insn "*sqrtdf2_sse"
15531
  [(set (match_operand:DF 0 "register_operand" "=Y")
15532
        (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15533
  "TARGET_SSE2 && TARGET_SSE_MATH"
15534
  "sqrtsd\t{%1, %0|%0, %1}"
15535
  [(set_attr "type" "sse")
15536
   (set_attr "mode" "DF")
15537
   (set_attr "athlon_decode" "*")])
15538
 
15539
(define_insn "*sqrtdf2_i387"
15540
  [(set (match_operand:DF 0 "register_operand" "=f")
15541
        (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15542
  "TARGET_USE_FANCY_MATH_387"
15543
  "fsqrt"
15544
  [(set_attr "type" "fpspc")
15545
   (set_attr "mode" "DF")
15546
   (set_attr "athlon_decode" "direct")])
15547
 
15548
(define_insn "*sqrtextendsfdf2_i387"
15549
  [(set (match_operand:DF 0 "register_operand" "=f")
15550
        (sqrt:DF (float_extend:DF
15551
                  (match_operand:SF 1 "register_operand" "0"))))]
15552
  "TARGET_USE_FANCY_MATH_387
15553
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15554
  "fsqrt"
15555
  [(set_attr "type" "fpspc")
15556
   (set_attr "mode" "DF")
15557
   (set_attr "athlon_decode" "direct")])
15558
 
15559
(define_insn "sqrtxf2"
15560
  [(set (match_operand:XF 0 "register_operand" "=f")
15561
        (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562
  "TARGET_USE_FANCY_MATH_387"
15563
  "fsqrt"
15564
  [(set_attr "type" "fpspc")
15565
   (set_attr "mode" "XF")
15566
   (set_attr "athlon_decode" "direct")])
15567
 
15568
(define_insn "*sqrtextendsfxf2_i387"
15569
  [(set (match_operand:XF 0 "register_operand" "=f")
15570
        (sqrt:XF (float_extend:XF
15571
                  (match_operand:SF 1 "register_operand" "0"))))]
15572
  "TARGET_USE_FANCY_MATH_387"
15573
  "fsqrt"
15574
  [(set_attr "type" "fpspc")
15575
   (set_attr "mode" "XF")
15576
   (set_attr "athlon_decode" "direct")])
15577
 
15578
(define_insn "*sqrtextenddfxf2_i387"
15579
  [(set (match_operand:XF 0 "register_operand" "=f")
15580
        (sqrt:XF (float_extend:XF
15581
                  (match_operand:DF 1 "register_operand" "0"))))]
15582
  "TARGET_USE_FANCY_MATH_387"
15583
  "fsqrt"
15584
  [(set_attr "type" "fpspc")
15585
   (set_attr "mode" "XF")
15586
   (set_attr "athlon_decode" "direct")])
15587
 
15588
(define_insn "fpremxf4"
15589
  [(set (match_operand:XF 0 "register_operand" "=f")
15590
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15591
                    (match_operand:XF 3 "register_operand" "1")]
15592
                   UNSPEC_FPREM_F))
15593
   (set (match_operand:XF 1 "register_operand" "=u")
15594
        (unspec:XF [(match_dup 2) (match_dup 3)]
15595
                   UNSPEC_FPREM_U))
15596
   (set (reg:CCFP FPSR_REG)
15597
        (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15598
  "TARGET_USE_FANCY_MATH_387
15599
   && flag_unsafe_math_optimizations"
15600
  "fprem"
15601
  [(set_attr "type" "fpspc")
15602
   (set_attr "mode" "XF")])
15603
 
15604
(define_expand "fmodsf3"
15605
  [(use (match_operand:SF 0 "register_operand" ""))
15606
   (use (match_operand:SF 1 "register_operand" ""))
15607
   (use (match_operand:SF 2 "register_operand" ""))]
15608
  "TARGET_USE_FANCY_MATH_387
15609
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15610
   && flag_unsafe_math_optimizations"
15611
{
15612
  rtx label = gen_label_rtx ();
15613
 
15614
  rtx op1 = gen_reg_rtx (XFmode);
15615
  rtx op2 = gen_reg_rtx (XFmode);
15616
 
15617
  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15618
  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15619
 
15620
  emit_label (label);
15621
 
15622
  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15623
  ix86_emit_fp_unordered_jump (label);
15624
 
15625
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15626
  DONE;
15627
})
15628
 
15629
(define_expand "fmoddf3"
15630
  [(use (match_operand:DF 0 "register_operand" ""))
15631
   (use (match_operand:DF 1 "register_operand" ""))
15632
   (use (match_operand:DF 2 "register_operand" ""))]
15633
  "TARGET_USE_FANCY_MATH_387
15634
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15635
   && flag_unsafe_math_optimizations"
15636
{
15637
  rtx label = gen_label_rtx ();
15638
 
15639
  rtx op1 = gen_reg_rtx (XFmode);
15640
  rtx op2 = gen_reg_rtx (XFmode);
15641
 
15642
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15643
  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15644
 
15645
  emit_label (label);
15646
 
15647
  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15648
  ix86_emit_fp_unordered_jump (label);
15649
 
15650
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15651
  DONE;
15652
})
15653
 
15654
(define_expand "fmodxf3"
15655
  [(use (match_operand:XF 0 "register_operand" ""))
15656
   (use (match_operand:XF 1 "register_operand" ""))
15657
   (use (match_operand:XF 2 "register_operand" ""))]
15658
  "TARGET_USE_FANCY_MATH_387
15659
   && flag_unsafe_math_optimizations"
15660
{
15661
  rtx label = gen_label_rtx ();
15662
 
15663
  emit_label (label);
15664
 
15665
  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15666
                           operands[1], operands[2]));
15667
  ix86_emit_fp_unordered_jump (label);
15668
 
15669
  emit_move_insn (operands[0], operands[1]);
15670
  DONE;
15671
})
15672
 
15673
(define_insn "fprem1xf4"
15674
  [(set (match_operand:XF 0 "register_operand" "=f")
15675
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15676
                    (match_operand:XF 3 "register_operand" "1")]
15677
                   UNSPEC_FPREM1_F))
15678
   (set (match_operand:XF 1 "register_operand" "=u")
15679
        (unspec:XF [(match_dup 2) (match_dup 3)]
15680
                   UNSPEC_FPREM1_U))
15681
   (set (reg:CCFP FPSR_REG)
15682
        (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15683
  "TARGET_USE_FANCY_MATH_387
15684
   && flag_unsafe_math_optimizations"
15685
  "fprem1"
15686
  [(set_attr "type" "fpspc")
15687
   (set_attr "mode" "XF")])
15688
 
15689
(define_expand "dremsf3"
15690
  [(use (match_operand:SF 0 "register_operand" ""))
15691
   (use (match_operand:SF 1 "register_operand" ""))
15692
   (use (match_operand:SF 2 "register_operand" ""))]
15693
  "TARGET_USE_FANCY_MATH_387
15694
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15695
   && flag_unsafe_math_optimizations"
15696
{
15697
  rtx label = gen_label_rtx ();
15698
 
15699
  rtx op1 = gen_reg_rtx (XFmode);
15700
  rtx op2 = gen_reg_rtx (XFmode);
15701
 
15702
  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15703
  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15704
 
15705
  emit_label (label);
15706
 
15707
  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15708
  ix86_emit_fp_unordered_jump (label);
15709
 
15710
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15711
  DONE;
15712
})
15713
 
15714
(define_expand "dremdf3"
15715
  [(use (match_operand:DF 0 "register_operand" ""))
15716
   (use (match_operand:DF 1 "register_operand" ""))
15717
   (use (match_operand:DF 2 "register_operand" ""))]
15718
  "TARGET_USE_FANCY_MATH_387
15719
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15720
   && flag_unsafe_math_optimizations"
15721
{
15722
  rtx label = gen_label_rtx ();
15723
 
15724
  rtx op1 = gen_reg_rtx (XFmode);
15725
  rtx op2 = gen_reg_rtx (XFmode);
15726
 
15727
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15728
  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15729
 
15730
  emit_label (label);
15731
 
15732
  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15733
  ix86_emit_fp_unordered_jump (label);
15734
 
15735
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15736
  DONE;
15737
})
15738
 
15739
(define_expand "dremxf3"
15740
  [(use (match_operand:XF 0 "register_operand" ""))
15741
   (use (match_operand:XF 1 "register_operand" ""))
15742
   (use (match_operand:XF 2 "register_operand" ""))]
15743
  "TARGET_USE_FANCY_MATH_387
15744
   && flag_unsafe_math_optimizations"
15745
{
15746
  rtx label = gen_label_rtx ();
15747
 
15748
  emit_label (label);
15749
 
15750
  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15751
                            operands[1], operands[2]));
15752
  ix86_emit_fp_unordered_jump (label);
15753
 
15754
  emit_move_insn (operands[0], operands[1]);
15755
  DONE;
15756
})
15757
 
15758
(define_insn "*sindf2"
15759
  [(set (match_operand:DF 0 "register_operand" "=f")
15760
        (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15761
  "TARGET_USE_FANCY_MATH_387
15762
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15763
   && flag_unsafe_math_optimizations"
15764
  "fsin"
15765
  [(set_attr "type" "fpspc")
15766
   (set_attr "mode" "DF")])
15767
 
15768
(define_insn "*sinsf2"
15769
  [(set (match_operand:SF 0 "register_operand" "=f")
15770
        (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15771
  "TARGET_USE_FANCY_MATH_387
15772
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15773
   && flag_unsafe_math_optimizations"
15774
  "fsin"
15775
  [(set_attr "type" "fpspc")
15776
   (set_attr "mode" "SF")])
15777
 
15778
(define_insn "*sinextendsfdf2"
15779
  [(set (match_operand:DF 0 "register_operand" "=f")
15780
        (unspec:DF [(float_extend:DF
15781
                     (match_operand:SF 1 "register_operand" "0"))]
15782
                   UNSPEC_SIN))]
15783
  "TARGET_USE_FANCY_MATH_387
15784
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15785
   && flag_unsafe_math_optimizations"
15786
  "fsin"
15787
  [(set_attr "type" "fpspc")
15788
   (set_attr "mode" "DF")])
15789
 
15790
(define_insn "*sinxf2"
15791
  [(set (match_operand:XF 0 "register_operand" "=f")
15792
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15793
  "TARGET_USE_FANCY_MATH_387
15794
   && flag_unsafe_math_optimizations"
15795
  "fsin"
15796
  [(set_attr "type" "fpspc")
15797
   (set_attr "mode" "XF")])
15798
 
15799
(define_insn "*cosdf2"
15800
  [(set (match_operand:DF 0 "register_operand" "=f")
15801
        (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15802
  "TARGET_USE_FANCY_MATH_387
15803
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15804
   && flag_unsafe_math_optimizations"
15805
  "fcos"
15806
  [(set_attr "type" "fpspc")
15807
   (set_attr "mode" "DF")])
15808
 
15809
(define_insn "*cossf2"
15810
  [(set (match_operand:SF 0 "register_operand" "=f")
15811
        (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15812
  "TARGET_USE_FANCY_MATH_387
15813
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15814
   && flag_unsafe_math_optimizations"
15815
  "fcos"
15816
  [(set_attr "type" "fpspc")
15817
   (set_attr "mode" "SF")])
15818
 
15819
(define_insn "*cosextendsfdf2"
15820
  [(set (match_operand:DF 0 "register_operand" "=f")
15821
        (unspec:DF [(float_extend:DF
15822
                     (match_operand:SF 1 "register_operand" "0"))]
15823
                   UNSPEC_COS))]
15824
  "TARGET_USE_FANCY_MATH_387
15825
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15826
   && flag_unsafe_math_optimizations"
15827
  "fcos"
15828
  [(set_attr "type" "fpspc")
15829
   (set_attr "mode" "DF")])
15830
 
15831
(define_insn "*cosxf2"
15832
  [(set (match_operand:XF 0 "register_operand" "=f")
15833
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15834
  "TARGET_USE_FANCY_MATH_387
15835
   && flag_unsafe_math_optimizations"
15836
  "fcos"
15837
  [(set_attr "type" "fpspc")
15838
   (set_attr "mode" "XF")])
15839
 
15840
;; With sincos pattern defined, sin and cos builtin function will be
15841
;; expanded to sincos pattern with one of its outputs left unused.
15842
;; Cse pass  will detected, if two sincos patterns can be combined,
15843
;; otherwise sincos pattern will be split back to sin or cos pattern,
15844
;; depending on the unused output.
15845
 
15846
(define_insn "sincosdf3"
15847
  [(set (match_operand:DF 0 "register_operand" "=f")
15848
        (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15849
                   UNSPEC_SINCOS_COS))
15850
   (set (match_operand:DF 1 "register_operand" "=u")
15851
        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15852
  "TARGET_USE_FANCY_MATH_387
15853
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15854
   && flag_unsafe_math_optimizations"
15855
  "fsincos"
15856
  [(set_attr "type" "fpspc")
15857
   (set_attr "mode" "DF")])
15858
 
15859
(define_split
15860
  [(set (match_operand:DF 0 "register_operand" "")
15861
        (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15862
                   UNSPEC_SINCOS_COS))
15863
   (set (match_operand:DF 1 "register_operand" "")
15864
        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15865
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15866
   && !reload_completed && !reload_in_progress"
15867
  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15868
  "")
15869
 
15870
(define_split
15871
  [(set (match_operand:DF 0 "register_operand" "")
15872
        (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15873
                   UNSPEC_SINCOS_COS))
15874
   (set (match_operand:DF 1 "register_operand" "")
15875
        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15876
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15877
   && !reload_completed && !reload_in_progress"
15878
  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15879
  "")
15880
 
15881
(define_insn "sincossf3"
15882
  [(set (match_operand:SF 0 "register_operand" "=f")
15883
        (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15884
                   UNSPEC_SINCOS_COS))
15885
   (set (match_operand:SF 1 "register_operand" "=u")
15886
        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15887
  "TARGET_USE_FANCY_MATH_387
15888
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15889
   && flag_unsafe_math_optimizations"
15890
  "fsincos"
15891
  [(set_attr "type" "fpspc")
15892
   (set_attr "mode" "SF")])
15893
 
15894
(define_split
15895
  [(set (match_operand:SF 0 "register_operand" "")
15896
        (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15897
                   UNSPEC_SINCOS_COS))
15898
   (set (match_operand:SF 1 "register_operand" "")
15899
        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15900
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15901
   && !reload_completed && !reload_in_progress"
15902
  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15903
  "")
15904
 
15905
(define_split
15906
  [(set (match_operand:SF 0 "register_operand" "")
15907
        (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15908
                   UNSPEC_SINCOS_COS))
15909
   (set (match_operand:SF 1 "register_operand" "")
15910
        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15911
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15912
   && !reload_completed && !reload_in_progress"
15913
  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15914
  "")
15915
 
15916
(define_insn "*sincosextendsfdf3"
15917
  [(set (match_operand:DF 0 "register_operand" "=f")
15918
        (unspec:DF [(float_extend:DF
15919
                     (match_operand:SF 2 "register_operand" "0"))]
15920
                   UNSPEC_SINCOS_COS))
15921
   (set (match_operand:DF 1 "register_operand" "=u")
15922
        (unspec:DF [(float_extend:DF
15923
                     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15924
  "TARGET_USE_FANCY_MATH_387
15925
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15926
   && flag_unsafe_math_optimizations"
15927
  "fsincos"
15928
  [(set_attr "type" "fpspc")
15929
   (set_attr "mode" "DF")])
15930
 
15931
(define_split
15932
  [(set (match_operand:DF 0 "register_operand" "")
15933
        (unspec:DF [(float_extend:DF
15934
                     (match_operand:SF 2 "register_operand" ""))]
15935
                   UNSPEC_SINCOS_COS))
15936
   (set (match_operand:DF 1 "register_operand" "")
15937
        (unspec:DF [(float_extend:DF
15938
                     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15939
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15940
   && !reload_completed && !reload_in_progress"
15941
  [(set (match_dup 1) (unspec:DF [(float_extend:DF
15942
                                   (match_dup 2))] UNSPEC_SIN))]
15943
  "")
15944
 
15945
(define_split
15946
  [(set (match_operand:DF 0 "register_operand" "")
15947
        (unspec:DF [(float_extend:DF
15948
                     (match_operand:SF 2 "register_operand" ""))]
15949
                   UNSPEC_SINCOS_COS))
15950
   (set (match_operand:DF 1 "register_operand" "")
15951
        (unspec:DF [(float_extend:DF
15952
                     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15953
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15954
   && !reload_completed && !reload_in_progress"
15955
  [(set (match_dup 0) (unspec:DF [(float_extend:DF
15956
                                   (match_dup 2))] UNSPEC_COS))]
15957
  "")
15958
 
15959
(define_insn "sincosxf3"
15960
  [(set (match_operand:XF 0 "register_operand" "=f")
15961
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15962
                   UNSPEC_SINCOS_COS))
15963
   (set (match_operand:XF 1 "register_operand" "=u")
15964
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15965
  "TARGET_USE_FANCY_MATH_387
15966
   && flag_unsafe_math_optimizations"
15967
  "fsincos"
15968
  [(set_attr "type" "fpspc")
15969
   (set_attr "mode" "XF")])
15970
 
15971
(define_split
15972
  [(set (match_operand:XF 0 "register_operand" "")
15973
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15974
                   UNSPEC_SINCOS_COS))
15975
   (set (match_operand:XF 1 "register_operand" "")
15976
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15977
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15978
   && !reload_completed && !reload_in_progress"
15979
  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15980
  "")
15981
 
15982
(define_split
15983
  [(set (match_operand:XF 0 "register_operand" "")
15984
        (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15985
                   UNSPEC_SINCOS_COS))
15986
   (set (match_operand:XF 1 "register_operand" "")
15987
        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15988
  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15989
   && !reload_completed && !reload_in_progress"
15990
  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15991
  "")
15992
 
15993
(define_insn "*tandf3_1"
15994
  [(set (match_operand:DF 0 "register_operand" "=f")
15995
        (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15996
                   UNSPEC_TAN_ONE))
15997
   (set (match_operand:DF 1 "register_operand" "=u")
15998
        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15999
  "TARGET_USE_FANCY_MATH_387
16000
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16001
   && flag_unsafe_math_optimizations"
16002
  "fptan"
16003
  [(set_attr "type" "fpspc")
16004
   (set_attr "mode" "DF")])
16005
 
16006
;; optimize sequence: fptan
16007
;;                    fstp    %st(0)
16008
;;                    fld1
16009
;; into fptan insn.
16010
 
16011
(define_peephole2
16012
  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16013
                  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16014
                             UNSPEC_TAN_ONE))
16015
             (set (match_operand:DF 1 "register_operand" "")
16016
                  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16017
   (set (match_dup 0)
16018
        (match_operand:DF 3 "immediate_operand" ""))]
16019
  "standard_80387_constant_p (operands[3]) == 2"
16020
  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16021
             (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16022
  "")
16023
 
16024
(define_expand "tandf2"
16025
  [(parallel [(set (match_dup 2)
16026
                   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16027
                              UNSPEC_TAN_ONE))
16028
              (set (match_operand:DF 0 "register_operand" "")
16029
                   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16030
  "TARGET_USE_FANCY_MATH_387
16031
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16032
   && flag_unsafe_math_optimizations"
16033
{
16034
  operands[2] = gen_reg_rtx (DFmode);
16035
})
16036
 
16037
(define_insn "*tansf3_1"
16038
  [(set (match_operand:SF 0 "register_operand" "=f")
16039
        (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16040
                   UNSPEC_TAN_ONE))
16041
   (set (match_operand:SF 1 "register_operand" "=u")
16042
        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16043
  "TARGET_USE_FANCY_MATH_387
16044
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16045
   && flag_unsafe_math_optimizations"
16046
  "fptan"
16047
  [(set_attr "type" "fpspc")
16048
   (set_attr "mode" "SF")])
16049
 
16050
;; optimize sequence: fptan
16051
;;                    fstp    %st(0)
16052
;;                    fld1
16053
;; into fptan insn.
16054
 
16055
(define_peephole2
16056
  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16057
                  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16058
                             UNSPEC_TAN_ONE))
16059
             (set (match_operand:SF 1 "register_operand" "")
16060
                  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16061
   (set (match_dup 0)
16062
        (match_operand:SF 3 "immediate_operand" ""))]
16063
  "standard_80387_constant_p (operands[3]) == 2"
16064
  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16065
             (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16066
  "")
16067
 
16068
(define_expand "tansf2"
16069
  [(parallel [(set (match_dup 2)
16070
                   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16071
                              UNSPEC_TAN_ONE))
16072
              (set (match_operand:SF 0 "register_operand" "")
16073
                   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16074
  "TARGET_USE_FANCY_MATH_387
16075
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16076
   && flag_unsafe_math_optimizations"
16077
{
16078
  operands[2] = gen_reg_rtx (SFmode);
16079
})
16080
 
16081
(define_insn "*tanxf3_1"
16082
  [(set (match_operand:XF 0 "register_operand" "=f")
16083
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16084
                   UNSPEC_TAN_ONE))
16085
   (set (match_operand:XF 1 "register_operand" "=u")
16086
        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16087
  "TARGET_USE_FANCY_MATH_387
16088
   && flag_unsafe_math_optimizations"
16089
  "fptan"
16090
  [(set_attr "type" "fpspc")
16091
   (set_attr "mode" "XF")])
16092
 
16093
;; optimize sequence: fptan
16094
;;                    fstp    %st(0)
16095
;;                    fld1
16096
;; into fptan insn.
16097
 
16098
(define_peephole2
16099
  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16100
                  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16101
                             UNSPEC_TAN_ONE))
16102
             (set (match_operand:XF 1 "register_operand" "")
16103
                  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16104
   (set (match_dup 0)
16105
        (match_operand:XF 3 "immediate_operand" ""))]
16106
  "standard_80387_constant_p (operands[3]) == 2"
16107
  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16108
             (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16109
  "")
16110
 
16111
(define_expand "tanxf2"
16112
  [(parallel [(set (match_dup 2)
16113
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16114
                              UNSPEC_TAN_ONE))
16115
              (set (match_operand:XF 0 "register_operand" "")
16116
                   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16117
  "TARGET_USE_FANCY_MATH_387
16118
   && flag_unsafe_math_optimizations"
16119
{
16120
  operands[2] = gen_reg_rtx (XFmode);
16121
})
16122
 
16123
(define_insn "atan2df3_1"
16124
  [(set (match_operand:DF 0 "register_operand" "=f")
16125
        (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16126
                    (match_operand:DF 1 "register_operand" "u")]
16127
                   UNSPEC_FPATAN))
16128
   (clobber (match_scratch:DF 3 "=1"))]
16129
  "TARGET_USE_FANCY_MATH_387
16130
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16131
   && flag_unsafe_math_optimizations"
16132
  "fpatan"
16133
  [(set_attr "type" "fpspc")
16134
   (set_attr "mode" "DF")])
16135
 
16136
(define_expand "atan2df3"
16137
  [(use (match_operand:DF 0 "register_operand" ""))
16138
   (use (match_operand:DF 2 "register_operand" ""))
16139
   (use (match_operand:DF 1 "register_operand" ""))]
16140
  "TARGET_USE_FANCY_MATH_387
16141
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16142
   && flag_unsafe_math_optimizations"
16143
{
16144
  rtx copy = gen_reg_rtx (DFmode);
16145
  emit_move_insn (copy, operands[1]);
16146
  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16147
  DONE;
16148
})
16149
 
16150
(define_expand "atandf2"
16151
  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16152
                   (unspec:DF [(match_dup 2)
16153
                               (match_operand:DF 1 "register_operand" "")]
16154
                    UNSPEC_FPATAN))
16155
              (clobber (match_scratch:DF 3 ""))])]
16156
  "TARGET_USE_FANCY_MATH_387
16157
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16158
   && flag_unsafe_math_optimizations"
16159
{
16160
  operands[2] = gen_reg_rtx (DFmode);
16161
  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16162
})
16163
 
16164
(define_insn "atan2sf3_1"
16165
  [(set (match_operand:SF 0 "register_operand" "=f")
16166
        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16167
                    (match_operand:SF 1 "register_operand" "u")]
16168
                   UNSPEC_FPATAN))
16169
   (clobber (match_scratch:SF 3 "=1"))]
16170
  "TARGET_USE_FANCY_MATH_387
16171
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16172
   && flag_unsafe_math_optimizations"
16173
  "fpatan"
16174
  [(set_attr "type" "fpspc")
16175
   (set_attr "mode" "SF")])
16176
 
16177
(define_expand "atan2sf3"
16178
  [(use (match_operand:SF 0 "register_operand" ""))
16179
   (use (match_operand:SF 2 "register_operand" ""))
16180
   (use (match_operand:SF 1 "register_operand" ""))]
16181
  "TARGET_USE_FANCY_MATH_387
16182
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16183
   && flag_unsafe_math_optimizations"
16184
{
16185
  rtx copy = gen_reg_rtx (SFmode);
16186
  emit_move_insn (copy, operands[1]);
16187
  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16188
  DONE;
16189
})
16190
 
16191
(define_expand "atansf2"
16192
  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16193
                   (unspec:SF [(match_dup 2)
16194
                               (match_operand:SF 1 "register_operand" "")]
16195
                    UNSPEC_FPATAN))
16196
              (clobber (match_scratch:SF 3 ""))])]
16197
  "TARGET_USE_FANCY_MATH_387
16198
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16199
   && flag_unsafe_math_optimizations"
16200
{
16201
  operands[2] = gen_reg_rtx (SFmode);
16202
  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16203
})
16204
 
16205
(define_insn "atan2xf3_1"
16206
  [(set (match_operand:XF 0 "register_operand" "=f")
16207
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16208
                    (match_operand:XF 1 "register_operand" "u")]
16209
                   UNSPEC_FPATAN))
16210
   (clobber (match_scratch:XF 3 "=1"))]
16211
  "TARGET_USE_FANCY_MATH_387
16212
   && flag_unsafe_math_optimizations"
16213
  "fpatan"
16214
  [(set_attr "type" "fpspc")
16215
   (set_attr "mode" "XF")])
16216
 
16217
(define_expand "atan2xf3"
16218
  [(use (match_operand:XF 0 "register_operand" ""))
16219
   (use (match_operand:XF 2 "register_operand" ""))
16220
   (use (match_operand:XF 1 "register_operand" ""))]
16221
  "TARGET_USE_FANCY_MATH_387
16222
   && flag_unsafe_math_optimizations"
16223
{
16224
  rtx copy = gen_reg_rtx (XFmode);
16225
  emit_move_insn (copy, operands[1]);
16226
  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16227
  DONE;
16228
})
16229
 
16230
(define_expand "atanxf2"
16231
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16232
                   (unspec:XF [(match_dup 2)
16233
                               (match_operand:XF 1 "register_operand" "")]
16234
                    UNSPEC_FPATAN))
16235
              (clobber (match_scratch:XF 3 ""))])]
16236
  "TARGET_USE_FANCY_MATH_387
16237
   && flag_unsafe_math_optimizations"
16238
{
16239
  operands[2] = gen_reg_rtx (XFmode);
16240
  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16241
})
16242
 
16243
(define_expand "asindf2"
16244
  [(set (match_dup 2)
16245
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16246
   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16247
   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16248
   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16249
   (parallel [(set (match_dup 7)
16250
                   (unspec:XF [(match_dup 6) (match_dup 2)]
16251
                              UNSPEC_FPATAN))
16252
              (clobber (match_scratch:XF 8 ""))])
16253
   (set (match_operand:DF 0 "register_operand" "")
16254
        (float_truncate:DF (match_dup 7)))]
16255
  "TARGET_USE_FANCY_MATH_387
16256
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16257
   && flag_unsafe_math_optimizations"
16258
{
16259
  int i;
16260
 
16261
  for (i=2; i<8; i++)
16262
    operands[i] = gen_reg_rtx (XFmode);
16263
 
16264
  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16265
})
16266
 
16267
(define_expand "asinsf2"
16268
  [(set (match_dup 2)
16269
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16270
   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16271
   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16272
   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16273
   (parallel [(set (match_dup 7)
16274
                   (unspec:XF [(match_dup 6) (match_dup 2)]
16275
                              UNSPEC_FPATAN))
16276
              (clobber (match_scratch:XF 8 ""))])
16277
   (set (match_operand:SF 0 "register_operand" "")
16278
        (float_truncate:SF (match_dup 7)))]
16279
  "TARGET_USE_FANCY_MATH_387
16280
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16281
   && flag_unsafe_math_optimizations"
16282
{
16283
  int i;
16284
 
16285
  for (i=2; i<8; i++)
16286
    operands[i] = gen_reg_rtx (XFmode);
16287
 
16288
  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16289
})
16290
 
16291
(define_expand "asinxf2"
16292
  [(set (match_dup 2)
16293
        (mult:XF (match_operand:XF 1 "register_operand" "")
16294
                 (match_dup 1)))
16295
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16296
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16297
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16298
                   (unspec:XF [(match_dup 5) (match_dup 1)]
16299
                              UNSPEC_FPATAN))
16300
              (clobber (match_scratch:XF 6 ""))])]
16301
  "TARGET_USE_FANCY_MATH_387
16302
   && flag_unsafe_math_optimizations"
16303
{
16304
  int i;
16305
 
16306
  for (i=2; i<6; i++)
16307
    operands[i] = gen_reg_rtx (XFmode);
16308
 
16309
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16310
})
16311
 
16312
(define_expand "acosdf2"
16313
  [(set (match_dup 2)
16314
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16315
   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16316
   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16317
   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16318
   (parallel [(set (match_dup 7)
16319
                   (unspec:XF [(match_dup 2) (match_dup 6)]
16320
                              UNSPEC_FPATAN))
16321
              (clobber (match_scratch:XF 8 ""))])
16322
   (set (match_operand:DF 0 "register_operand" "")
16323
        (float_truncate:DF (match_dup 7)))]
16324
  "TARGET_USE_FANCY_MATH_387
16325
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16326
   && flag_unsafe_math_optimizations"
16327
{
16328
  int i;
16329
 
16330
  for (i=2; i<8; i++)
16331
    operands[i] = gen_reg_rtx (XFmode);
16332
 
16333
  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16334
})
16335
 
16336
(define_expand "acossf2"
16337
  [(set (match_dup 2)
16338
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16339
   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16340
   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16341
   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16342
   (parallel [(set (match_dup 7)
16343
                   (unspec:XF [(match_dup 2) (match_dup 6)]
16344
                              UNSPEC_FPATAN))
16345
              (clobber (match_scratch:XF 8 ""))])
16346
   (set (match_operand:SF 0 "register_operand" "")
16347
        (float_truncate:SF (match_dup 7)))]
16348
  "TARGET_USE_FANCY_MATH_387
16349
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16350
   && flag_unsafe_math_optimizations"
16351
{
16352
  int i;
16353
 
16354
  for (i=2; i<8; i++)
16355
    operands[i] = gen_reg_rtx (XFmode);
16356
 
16357
  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16358
})
16359
 
16360
(define_expand "acosxf2"
16361
  [(set (match_dup 2)
16362
        (mult:XF (match_operand:XF 1 "register_operand" "")
16363
                 (match_dup 1)))
16364
   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16365
   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16366
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16367
                   (unspec:XF [(match_dup 1) (match_dup 5)]
16368
                              UNSPEC_FPATAN))
16369
              (clobber (match_scratch:XF 6 ""))])]
16370
  "TARGET_USE_FANCY_MATH_387
16371
   && flag_unsafe_math_optimizations"
16372
{
16373
  int i;
16374
 
16375
  for (i=2; i<6; i++)
16376
    operands[i] = gen_reg_rtx (XFmode);
16377
 
16378
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16379
})
16380
 
16381
(define_insn "fyl2x_xf3"
16382
  [(set (match_operand:XF 0 "register_operand" "=f")
16383
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16384
                    (match_operand:XF 1 "register_operand" "u")]
16385
                   UNSPEC_FYL2X))
16386
   (clobber (match_scratch:XF 3 "=1"))]
16387
  "TARGET_USE_FANCY_MATH_387
16388
   && flag_unsafe_math_optimizations"
16389
  "fyl2x"
16390
  [(set_attr "type" "fpspc")
16391
   (set_attr "mode" "XF")])
16392
 
16393
(define_expand "logsf2"
16394
  [(set (match_dup 2)
16395
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16396
   (parallel [(set (match_dup 4)
16397
                   (unspec:XF [(match_dup 2)
16398
                               (match_dup 3)] UNSPEC_FYL2X))
16399
              (clobber (match_scratch:XF 5 ""))])
16400
   (set (match_operand:SF 0 "register_operand" "")
16401
        (float_truncate:SF (match_dup 4)))]
16402
  "TARGET_USE_FANCY_MATH_387
16403
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16404
   && flag_unsafe_math_optimizations"
16405
{
16406
  rtx temp;
16407
 
16408
  operands[2] = gen_reg_rtx (XFmode);
16409
  operands[3] = gen_reg_rtx (XFmode);
16410
  operands[4] = gen_reg_rtx (XFmode);
16411
 
16412
  temp = standard_80387_constant_rtx (4); /* fldln2 */
16413
  emit_move_insn (operands[3], temp);
16414
})
16415
 
16416
(define_expand "logdf2"
16417
  [(set (match_dup 2)
16418
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16419
   (parallel [(set (match_dup 4)
16420
                   (unspec:XF [(match_dup 2)
16421
                               (match_dup 3)] UNSPEC_FYL2X))
16422
              (clobber (match_scratch:XF 5 ""))])
16423
   (set (match_operand:DF 0 "register_operand" "")
16424
        (float_truncate:DF (match_dup 4)))]
16425
  "TARGET_USE_FANCY_MATH_387
16426
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16427
   && flag_unsafe_math_optimizations"
16428
{
16429
  rtx temp;
16430
 
16431
  operands[2] = gen_reg_rtx (XFmode);
16432
  operands[3] = gen_reg_rtx (XFmode);
16433
  operands[4] = gen_reg_rtx (XFmode);
16434
 
16435
  temp = standard_80387_constant_rtx (4); /* fldln2 */
16436
  emit_move_insn (operands[3], temp);
16437
})
16438
 
16439
(define_expand "logxf2"
16440
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16441
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16442
                               (match_dup 2)] UNSPEC_FYL2X))
16443
              (clobber (match_scratch:XF 3 ""))])]
16444
  "TARGET_USE_FANCY_MATH_387
16445
   && flag_unsafe_math_optimizations"
16446
{
16447
  rtx temp;
16448
 
16449
  operands[2] = gen_reg_rtx (XFmode);
16450
  temp = standard_80387_constant_rtx (4); /* fldln2 */
16451
  emit_move_insn (operands[2], temp);
16452
})
16453
 
16454
(define_expand "log10sf2"
16455
  [(set (match_dup 2)
16456
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16457
   (parallel [(set (match_dup 4)
16458
                   (unspec:XF [(match_dup 2)
16459
                               (match_dup 3)] UNSPEC_FYL2X))
16460
              (clobber (match_scratch:XF 5 ""))])
16461
   (set (match_operand:SF 0 "register_operand" "")
16462
        (float_truncate:SF (match_dup 4)))]
16463
  "TARGET_USE_FANCY_MATH_387
16464
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16465
   && flag_unsafe_math_optimizations"
16466
{
16467
  rtx temp;
16468
 
16469
  operands[2] = gen_reg_rtx (XFmode);
16470
  operands[3] = gen_reg_rtx (XFmode);
16471
  operands[4] = gen_reg_rtx (XFmode);
16472
 
16473
  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16474
  emit_move_insn (operands[3], temp);
16475
})
16476
 
16477
(define_expand "log10df2"
16478
  [(set (match_dup 2)
16479
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16480
   (parallel [(set (match_dup 4)
16481
                   (unspec:XF [(match_dup 2)
16482
                               (match_dup 3)] UNSPEC_FYL2X))
16483
              (clobber (match_scratch:XF 5 ""))])
16484
   (set (match_operand:DF 0 "register_operand" "")
16485
        (float_truncate:DF (match_dup 4)))]
16486
  "TARGET_USE_FANCY_MATH_387
16487
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16488
   && flag_unsafe_math_optimizations"
16489
{
16490
  rtx temp;
16491
 
16492
  operands[2] = gen_reg_rtx (XFmode);
16493
  operands[3] = gen_reg_rtx (XFmode);
16494
  operands[4] = gen_reg_rtx (XFmode);
16495
 
16496
  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16497
  emit_move_insn (operands[3], temp);
16498
})
16499
 
16500
(define_expand "log10xf2"
16501
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16502
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16503
                               (match_dup 2)] UNSPEC_FYL2X))
16504
              (clobber (match_scratch:XF 3 ""))])]
16505
  "TARGET_USE_FANCY_MATH_387
16506
   && flag_unsafe_math_optimizations"
16507
{
16508
  rtx temp;
16509
 
16510
  operands[2] = gen_reg_rtx (XFmode);
16511
  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16512
  emit_move_insn (operands[2], temp);
16513
})
16514
 
16515
(define_expand "log2sf2"
16516
  [(set (match_dup 2)
16517
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16518
   (parallel [(set (match_dup 4)
16519
                   (unspec:XF [(match_dup 2)
16520
                               (match_dup 3)] UNSPEC_FYL2X))
16521
              (clobber (match_scratch:XF 5 ""))])
16522
   (set (match_operand:SF 0 "register_operand" "")
16523
        (float_truncate:SF (match_dup 4)))]
16524
  "TARGET_USE_FANCY_MATH_387
16525
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16526
   && flag_unsafe_math_optimizations"
16527
{
16528
  operands[2] = gen_reg_rtx (XFmode);
16529
  operands[3] = gen_reg_rtx (XFmode);
16530
  operands[4] = gen_reg_rtx (XFmode);
16531
 
16532
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16533
})
16534
 
16535
(define_expand "log2df2"
16536
  [(set (match_dup 2)
16537
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16538
   (parallel [(set (match_dup 4)
16539
                   (unspec:XF [(match_dup 2)
16540
                               (match_dup 3)] UNSPEC_FYL2X))
16541
              (clobber (match_scratch:XF 5 ""))])
16542
   (set (match_operand:DF 0 "register_operand" "")
16543
        (float_truncate:DF (match_dup 4)))]
16544
  "TARGET_USE_FANCY_MATH_387
16545
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16546
   && flag_unsafe_math_optimizations"
16547
{
16548
  operands[2] = gen_reg_rtx (XFmode);
16549
  operands[3] = gen_reg_rtx (XFmode);
16550
  operands[4] = gen_reg_rtx (XFmode);
16551
 
16552
  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16553
})
16554
 
16555
(define_expand "log2xf2"
16556
  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16557
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16558
                               (match_dup 2)] UNSPEC_FYL2X))
16559
              (clobber (match_scratch:XF 3 ""))])]
16560
  "TARGET_USE_FANCY_MATH_387
16561
   && flag_unsafe_math_optimizations"
16562
{
16563
  operands[2] = gen_reg_rtx (XFmode);
16564
  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16565
})
16566
 
16567
(define_insn "fyl2xp1_xf3"
16568
  [(set (match_operand:XF 0 "register_operand" "=f")
16569
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16570
                    (match_operand:XF 1 "register_operand" "u")]
16571
                   UNSPEC_FYL2XP1))
16572
   (clobber (match_scratch:XF 3 "=1"))]
16573
  "TARGET_USE_FANCY_MATH_387
16574
   && flag_unsafe_math_optimizations"
16575
  "fyl2xp1"
16576
  [(set_attr "type" "fpspc")
16577
   (set_attr "mode" "XF")])
16578
 
16579
(define_expand "log1psf2"
16580
  [(use (match_operand:SF 0 "register_operand" ""))
16581
   (use (match_operand:SF 1 "register_operand" ""))]
16582
  "TARGET_USE_FANCY_MATH_387
16583
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16584
   && flag_unsafe_math_optimizations"
16585
{
16586
  rtx op0 = gen_reg_rtx (XFmode);
16587
  rtx op1 = gen_reg_rtx (XFmode);
16588
 
16589
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16590
  ix86_emit_i387_log1p (op0, op1);
16591
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16592
  DONE;
16593
})
16594
 
16595
(define_expand "log1pdf2"
16596
  [(use (match_operand:DF 0 "register_operand" ""))
16597
   (use (match_operand:DF 1 "register_operand" ""))]
16598
  "TARGET_USE_FANCY_MATH_387
16599
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16600
   && flag_unsafe_math_optimizations"
16601
{
16602
  rtx op0 = gen_reg_rtx (XFmode);
16603
  rtx op1 = gen_reg_rtx (XFmode);
16604
 
16605
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16606
  ix86_emit_i387_log1p (op0, op1);
16607
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16608
  DONE;
16609
})
16610
 
16611
(define_expand "log1pxf2"
16612
  [(use (match_operand:XF 0 "register_operand" ""))
16613
   (use (match_operand:XF 1 "register_operand" ""))]
16614
  "TARGET_USE_FANCY_MATH_387
16615
   && flag_unsafe_math_optimizations"
16616
{
16617
  ix86_emit_i387_log1p (operands[0], operands[1]);
16618
  DONE;
16619
})
16620
 
16621
(define_insn "*fxtractxf3"
16622
  [(set (match_operand:XF 0 "register_operand" "=f")
16623
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16624
                   UNSPEC_XTRACT_FRACT))
16625
   (set (match_operand:XF 1 "register_operand" "=u")
16626
        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16627
  "TARGET_USE_FANCY_MATH_387
16628
   && flag_unsafe_math_optimizations"
16629
  "fxtract"
16630
  [(set_attr "type" "fpspc")
16631
   (set_attr "mode" "XF")])
16632
 
16633
(define_expand "logbsf2"
16634
  [(set (match_dup 2)
16635
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16636
   (parallel [(set (match_dup 3)
16637
                   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16638
              (set (match_dup 4)
16639
                   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16640
   (set (match_operand:SF 0 "register_operand" "")
16641
        (float_truncate:SF (match_dup 4)))]
16642
  "TARGET_USE_FANCY_MATH_387
16643
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16644
   && flag_unsafe_math_optimizations"
16645
{
16646
  operands[2] = gen_reg_rtx (XFmode);
16647
  operands[3] = gen_reg_rtx (XFmode);
16648
  operands[4] = gen_reg_rtx (XFmode);
16649
})
16650
 
16651
(define_expand "logbdf2"
16652
  [(set (match_dup 2)
16653
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16654
   (parallel [(set (match_dup 3)
16655
                   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16656
              (set (match_dup 4)
16657
                   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16658
   (set (match_operand:DF 0 "register_operand" "")
16659
        (float_truncate:DF (match_dup 4)))]
16660
  "TARGET_USE_FANCY_MATH_387
16661
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16662
   && flag_unsafe_math_optimizations"
16663
{
16664
  operands[2] = gen_reg_rtx (XFmode);
16665
  operands[3] = gen_reg_rtx (XFmode);
16666
  operands[4] = gen_reg_rtx (XFmode);
16667
})
16668
 
16669
(define_expand "logbxf2"
16670
  [(parallel [(set (match_dup 2)
16671
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16672
                              UNSPEC_XTRACT_FRACT))
16673
              (set (match_operand:XF 0 "register_operand" "")
16674
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16675
  "TARGET_USE_FANCY_MATH_387
16676
   && flag_unsafe_math_optimizations"
16677
{
16678
  operands[2] = gen_reg_rtx (XFmode);
16679
})
16680
 
16681
(define_expand "ilogbsi2"
16682
  [(parallel [(set (match_dup 2)
16683
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16684
                              UNSPEC_XTRACT_FRACT))
16685
              (set (match_operand:XF 3 "register_operand" "")
16686
                   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16687
   (parallel [(set (match_operand:SI 0 "register_operand" "")
16688
                   (fix:SI (match_dup 3)))
16689
              (clobber (reg:CC FLAGS_REG))])]
16690
  "TARGET_USE_FANCY_MATH_387
16691
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16692
   && flag_unsafe_math_optimizations"
16693
{
16694
  operands[2] = gen_reg_rtx (XFmode);
16695
  operands[3] = gen_reg_rtx (XFmode);
16696
})
16697
 
16698
(define_insn "*f2xm1xf2"
16699
  [(set (match_operand:XF 0 "register_operand" "=f")
16700
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16701
         UNSPEC_F2XM1))]
16702
  "TARGET_USE_FANCY_MATH_387
16703
   && flag_unsafe_math_optimizations"
16704
  "f2xm1"
16705
  [(set_attr "type" "fpspc")
16706
   (set_attr "mode" "XF")])
16707
 
16708
(define_insn "*fscalexf4"
16709
  [(set (match_operand:XF 0 "register_operand" "=f")
16710
        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16711
                    (match_operand:XF 3 "register_operand" "1")]
16712
                   UNSPEC_FSCALE_FRACT))
16713
   (set (match_operand:XF 1 "register_operand" "=u")
16714
        (unspec:XF [(match_dup 2) (match_dup 3)]
16715
                   UNSPEC_FSCALE_EXP))]
16716
  "TARGET_USE_FANCY_MATH_387
16717
   && flag_unsafe_math_optimizations"
16718
  "fscale"
16719
  [(set_attr "type" "fpspc")
16720
   (set_attr "mode" "XF")])
16721
 
16722
(define_expand "expsf2"
16723
  [(set (match_dup 2)
16724
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16725
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16726
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16727
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16728
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16729
   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16730
   (parallel [(set (match_dup 10)
16731
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16732
                              UNSPEC_FSCALE_FRACT))
16733
              (set (match_dup 11)
16734
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16735
                              UNSPEC_FSCALE_EXP))])
16736
   (set (match_operand:SF 0 "register_operand" "")
16737
        (float_truncate:SF (match_dup 10)))]
16738
  "TARGET_USE_FANCY_MATH_387
16739
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16740
   && flag_unsafe_math_optimizations"
16741
{
16742
  rtx temp;
16743
  int i;
16744
 
16745
  for (i=2; i<12; i++)
16746
    operands[i] = gen_reg_rtx (XFmode);
16747
  temp = standard_80387_constant_rtx (5); /* fldl2e */
16748
  emit_move_insn (operands[3], temp);
16749
  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16750
})
16751
 
16752
(define_expand "expdf2"
16753
  [(set (match_dup 2)
16754
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16755
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16756
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16757
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16758
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16759
   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16760
   (parallel [(set (match_dup 10)
16761
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16762
                              UNSPEC_FSCALE_FRACT))
16763
              (set (match_dup 11)
16764
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16765
                              UNSPEC_FSCALE_EXP))])
16766
   (set (match_operand:DF 0 "register_operand" "")
16767
        (float_truncate:DF (match_dup 10)))]
16768
  "TARGET_USE_FANCY_MATH_387
16769
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16770
   && flag_unsafe_math_optimizations"
16771
{
16772
  rtx temp;
16773
  int i;
16774
 
16775
  for (i=2; i<12; i++)
16776
    operands[i] = gen_reg_rtx (XFmode);
16777
  temp = standard_80387_constant_rtx (5); /* fldl2e */
16778
  emit_move_insn (operands[3], temp);
16779
  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16780
})
16781
 
16782
(define_expand "expxf2"
16783
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16784
                               (match_dup 2)))
16785
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16786
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16787
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16788
   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16789
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16790
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16791
                              UNSPEC_FSCALE_FRACT))
16792
              (set (match_dup 9)
16793
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16794
                              UNSPEC_FSCALE_EXP))])]
16795
  "TARGET_USE_FANCY_MATH_387
16796
   && flag_unsafe_math_optimizations"
16797
{
16798
  rtx temp;
16799
  int i;
16800
 
16801
  for (i=2; i<10; i++)
16802
    operands[i] = gen_reg_rtx (XFmode);
16803
  temp = standard_80387_constant_rtx (5); /* fldl2e */
16804
  emit_move_insn (operands[2], temp);
16805
  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16806
})
16807
 
16808
(define_expand "exp10sf2"
16809
  [(set (match_dup 2)
16810
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16811
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16812
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16813
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16814
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16815
   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16816
   (parallel [(set (match_dup 10)
16817
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16818
                              UNSPEC_FSCALE_FRACT))
16819
              (set (match_dup 11)
16820
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16821
                              UNSPEC_FSCALE_EXP))])
16822
   (set (match_operand:SF 0 "register_operand" "")
16823
        (float_truncate:SF (match_dup 10)))]
16824
  "TARGET_USE_FANCY_MATH_387
16825
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16826
   && flag_unsafe_math_optimizations"
16827
{
16828
  rtx temp;
16829
  int i;
16830
 
16831
  for (i=2; i<12; i++)
16832
    operands[i] = gen_reg_rtx (XFmode);
16833
  temp = standard_80387_constant_rtx (6); /* fldl2t */
16834
  emit_move_insn (operands[3], temp);
16835
  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16836
})
16837
 
16838
(define_expand "exp10df2"
16839
  [(set (match_dup 2)
16840
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16841
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16842
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16843
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16844
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16845
   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16846
   (parallel [(set (match_dup 10)
16847
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16848
                              UNSPEC_FSCALE_FRACT))
16849
              (set (match_dup 11)
16850
                   (unspec:XF [(match_dup 9) (match_dup 5)]
16851
                              UNSPEC_FSCALE_EXP))])
16852
   (set (match_operand:DF 0 "register_operand" "")
16853
        (float_truncate:DF (match_dup 10)))]
16854
  "TARGET_USE_FANCY_MATH_387
16855
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16856
   && flag_unsafe_math_optimizations"
16857
{
16858
  rtx temp;
16859
  int i;
16860
 
16861
  for (i=2; i<12; i++)
16862
    operands[i] = gen_reg_rtx (XFmode);
16863
  temp = standard_80387_constant_rtx (6); /* fldl2t */
16864
  emit_move_insn (operands[3], temp);
16865
  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16866
})
16867
 
16868
(define_expand "exp10xf2"
16869
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16870
                               (match_dup 2)))
16871
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16872
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16873
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16874
   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16875
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16876
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16877
                              UNSPEC_FSCALE_FRACT))
16878
              (set (match_dup 9)
16879
                   (unspec:XF [(match_dup 8) (match_dup 4)]
16880
                              UNSPEC_FSCALE_EXP))])]
16881
  "TARGET_USE_FANCY_MATH_387
16882
   && flag_unsafe_math_optimizations"
16883
{
16884
  rtx temp;
16885
  int i;
16886
 
16887
  for (i=2; i<10; i++)
16888
    operands[i] = gen_reg_rtx (XFmode);
16889
  temp = standard_80387_constant_rtx (6); /* fldl2t */
16890
  emit_move_insn (operands[2], temp);
16891
  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16892
})
16893
 
16894
(define_expand "exp2sf2"
16895
  [(set (match_dup 2)
16896
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16897
   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16898
   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16899
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16900
   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16901
   (parallel [(set (match_dup 8)
16902
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16903
                              UNSPEC_FSCALE_FRACT))
16904
              (set (match_dup 9)
16905
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16906
                              UNSPEC_FSCALE_EXP))])
16907
   (set (match_operand:SF 0 "register_operand" "")
16908
        (float_truncate:SF (match_dup 8)))]
16909
  "TARGET_USE_FANCY_MATH_387
16910
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911
   && flag_unsafe_math_optimizations"
16912
{
16913
  int i;
16914
 
16915
  for (i=2; i<10; i++)
16916
    operands[i] = gen_reg_rtx (XFmode);
16917
  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16918
})
16919
 
16920
(define_expand "exp2df2"
16921
  [(set (match_dup 2)
16922
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16923
   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16924
   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16925
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16926
   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16927
   (parallel [(set (match_dup 8)
16928
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16929
                              UNSPEC_FSCALE_FRACT))
16930
              (set (match_dup 9)
16931
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16932
                              UNSPEC_FSCALE_EXP))])
16933
   (set (match_operand:DF 0 "register_operand" "")
16934
        (float_truncate:DF (match_dup 8)))]
16935
  "TARGET_USE_FANCY_MATH_387
16936
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16937
   && flag_unsafe_math_optimizations"
16938
{
16939
  int i;
16940
 
16941
  for (i=2; i<10; i++)
16942
    operands[i] = gen_reg_rtx (XFmode);
16943
  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16944
})
16945
 
16946
(define_expand "exp2xf2"
16947
  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16948
   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16949
   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16950
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16951
   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16952
   (parallel [(set (match_operand:XF 0 "register_operand" "")
16953
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16954
                              UNSPEC_FSCALE_FRACT))
16955
              (set (match_dup 8)
16956
                   (unspec:XF [(match_dup 7) (match_dup 3)]
16957
                              UNSPEC_FSCALE_EXP))])]
16958
  "TARGET_USE_FANCY_MATH_387
16959
   && flag_unsafe_math_optimizations"
16960
{
16961
  int i;
16962
 
16963
  for (i=2; i<9; i++)
16964
    operands[i] = gen_reg_rtx (XFmode);
16965
  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16966
})
16967
 
16968
(define_expand "expm1df2"
16969
  [(set (match_dup 2)
16970
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16971
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16972
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16973
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16974
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16975
   (parallel [(set (match_dup 8)
16976
                   (unspec:XF [(match_dup 7) (match_dup 5)]
16977
                              UNSPEC_FSCALE_FRACT))
16978
                   (set (match_dup 9)
16979
                   (unspec:XF [(match_dup 7) (match_dup 5)]
16980
                              UNSPEC_FSCALE_EXP))])
16981
   (parallel [(set (match_dup 11)
16982
                   (unspec:XF [(match_dup 10) (match_dup 9)]
16983
                              UNSPEC_FSCALE_FRACT))
16984
              (set (match_dup 12)
16985
                   (unspec:XF [(match_dup 10) (match_dup 9)]
16986
                              UNSPEC_FSCALE_EXP))])
16987
   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16988
   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16989
   (set (match_operand:DF 0 "register_operand" "")
16990
        (float_truncate:DF (match_dup 14)))]
16991
  "TARGET_USE_FANCY_MATH_387
16992
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16993
   && flag_unsafe_math_optimizations"
16994
{
16995
  rtx temp;
16996
  int i;
16997
 
16998
  for (i=2; i<15; i++)
16999
    operands[i] = gen_reg_rtx (XFmode);
17000
  temp = standard_80387_constant_rtx (5); /* fldl2e */
17001
  emit_move_insn (operands[3], temp);
17002
  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17003
})
17004
 
17005
(define_expand "expm1sf2"
17006
  [(set (match_dup 2)
17007
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17008
   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17009
   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17010
   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17011
   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17012
   (parallel [(set (match_dup 8)
17013
                   (unspec:XF [(match_dup 7) (match_dup 5)]
17014
                              UNSPEC_FSCALE_FRACT))
17015
                   (set (match_dup 9)
17016
                   (unspec:XF [(match_dup 7) (match_dup 5)]
17017
                              UNSPEC_FSCALE_EXP))])
17018
   (parallel [(set (match_dup 11)
17019
                   (unspec:XF [(match_dup 10) (match_dup 9)]
17020
                              UNSPEC_FSCALE_FRACT))
17021
              (set (match_dup 12)
17022
                   (unspec:XF [(match_dup 10) (match_dup 9)]
17023
                              UNSPEC_FSCALE_EXP))])
17024
   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17025
   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17026
   (set (match_operand:SF 0 "register_operand" "")
17027
        (float_truncate:SF (match_dup 14)))]
17028
  "TARGET_USE_FANCY_MATH_387
17029
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17030
   && flag_unsafe_math_optimizations"
17031
{
17032
  rtx temp;
17033
  int i;
17034
 
17035
  for (i=2; i<15; i++)
17036
    operands[i] = gen_reg_rtx (XFmode);
17037
  temp = standard_80387_constant_rtx (5); /* fldl2e */
17038
  emit_move_insn (operands[3], temp);
17039
  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17040
})
17041
 
17042
(define_expand "expm1xf2"
17043
  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17044
                               (match_dup 2)))
17045
   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17046
   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17047
   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17048
   (parallel [(set (match_dup 7)
17049
                   (unspec:XF [(match_dup 6) (match_dup 4)]
17050
                              UNSPEC_FSCALE_FRACT))
17051
                   (set (match_dup 8)
17052
                   (unspec:XF [(match_dup 6) (match_dup 4)]
17053
                              UNSPEC_FSCALE_EXP))])
17054
   (parallel [(set (match_dup 10)
17055
                   (unspec:XF [(match_dup 9) (match_dup 8)]
17056
                              UNSPEC_FSCALE_FRACT))
17057
              (set (match_dup 11)
17058
                   (unspec:XF [(match_dup 9) (match_dup 8)]
17059
                              UNSPEC_FSCALE_EXP))])
17060
   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17061
   (set (match_operand:XF 0 "register_operand" "")
17062
        (plus:XF (match_dup 12) (match_dup 7)))]
17063
  "TARGET_USE_FANCY_MATH_387
17064
   && flag_unsafe_math_optimizations"
17065
{
17066
  rtx temp;
17067
  int i;
17068
 
17069
  for (i=2; i<13; i++)
17070
    operands[i] = gen_reg_rtx (XFmode);
17071
  temp = standard_80387_constant_rtx (5); /* fldl2e */
17072
  emit_move_insn (operands[2], temp);
17073
  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17074
})
17075
 
17076
(define_expand "ldexpdf3"
17077
  [(set (match_dup 3)
17078
        (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17079
   (set (match_dup 4)
17080
        (float:XF (match_operand:SI 2 "register_operand" "")))
17081
   (parallel [(set (match_dup 5)
17082
                   (unspec:XF [(match_dup 3) (match_dup 4)]
17083
                              UNSPEC_FSCALE_FRACT))
17084
              (set (match_dup 6)
17085
                   (unspec:XF [(match_dup 3) (match_dup 4)]
17086
                              UNSPEC_FSCALE_EXP))])
17087
   (set (match_operand:DF 0 "register_operand" "")
17088
        (float_truncate:DF (match_dup 5)))]
17089
  "TARGET_USE_FANCY_MATH_387
17090
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17091
   && flag_unsafe_math_optimizations"
17092
{
17093
  int i;
17094
 
17095
  for (i=3; i<7; i++)
17096
    operands[i] = gen_reg_rtx (XFmode);
17097
})
17098
 
17099
(define_expand "ldexpsf3"
17100
  [(set (match_dup 3)
17101
        (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17102
   (set (match_dup 4)
17103
        (float:XF (match_operand:SI 2 "register_operand" "")))
17104
   (parallel [(set (match_dup 5)
17105
                   (unspec:XF [(match_dup 3) (match_dup 4)]
17106
                              UNSPEC_FSCALE_FRACT))
17107
              (set (match_dup 6)
17108
                   (unspec:XF [(match_dup 3) (match_dup 4)]
17109
                              UNSPEC_FSCALE_EXP))])
17110
   (set (match_operand:SF 0 "register_operand" "")
17111
        (float_truncate:SF (match_dup 5)))]
17112
  "TARGET_USE_FANCY_MATH_387
17113
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17114
   && flag_unsafe_math_optimizations"
17115
{
17116
  int i;
17117
 
17118
  for (i=3; i<7; i++)
17119
    operands[i] = gen_reg_rtx (XFmode);
17120
})
17121
 
17122
(define_expand "ldexpxf3"
17123
  [(set (match_dup 3)
17124
        (float:XF (match_operand:SI 2 "register_operand" "")))
17125
   (parallel [(set (match_operand:XF 0 " register_operand" "")
17126
                   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17127
                               (match_dup 3)]
17128
                              UNSPEC_FSCALE_FRACT))
17129
              (set (match_dup 4)
17130
                   (unspec:XF [(match_dup 1) (match_dup 3)]
17131
                              UNSPEC_FSCALE_EXP))])]
17132
  "TARGET_USE_FANCY_MATH_387
17133
   && flag_unsafe_math_optimizations"
17134
{
17135
  int i;
17136
 
17137
  for (i=3; i<5; i++)
17138
    operands[i] = gen_reg_rtx (XFmode);
17139
})
17140
 
17141
 
17142
(define_insn "frndintxf2"
17143
  [(set (match_operand:XF 0 "register_operand" "=f")
17144
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17145
         UNSPEC_FRNDINT))]
17146
  "TARGET_USE_FANCY_MATH_387
17147
   && flag_unsafe_math_optimizations"
17148
  "frndint"
17149
  [(set_attr "type" "fpspc")
17150
   (set_attr "mode" "XF")])
17151
 
17152
(define_expand "rintdf2"
17153
  [(use (match_operand:DF 0 "register_operand" ""))
17154
   (use (match_operand:DF 1 "register_operand" ""))]
17155
  "TARGET_USE_FANCY_MATH_387
17156
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17157
   && flag_unsafe_math_optimizations"
17158
{
17159
  rtx op0 = gen_reg_rtx (XFmode);
17160
  rtx op1 = gen_reg_rtx (XFmode);
17161
 
17162
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17163
  emit_insn (gen_frndintxf2 (op0, op1));
17164
 
17165
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17166
  DONE;
17167
})
17168
 
17169
(define_expand "rintsf2"
17170
  [(use (match_operand:SF 0 "register_operand" ""))
17171
   (use (match_operand:SF 1 "register_operand" ""))]
17172
  "TARGET_USE_FANCY_MATH_387
17173
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17174
   && flag_unsafe_math_optimizations"
17175
{
17176
  rtx op0 = gen_reg_rtx (XFmode);
17177
  rtx op1 = gen_reg_rtx (XFmode);
17178
 
17179
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17180
  emit_insn (gen_frndintxf2 (op0, op1));
17181
 
17182
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17183
  DONE;
17184
})
17185
 
17186
(define_expand "rintxf2"
17187
  [(use (match_operand:XF 0 "register_operand" ""))
17188
   (use (match_operand:XF 1 "register_operand" ""))]
17189
  "TARGET_USE_FANCY_MATH_387
17190
   && flag_unsafe_math_optimizations"
17191
{
17192
  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17193
  DONE;
17194
})
17195
 
17196
(define_insn_and_split "*fistdi2_1"
17197
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17198
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17199
         UNSPEC_FIST))]
17200
  "TARGET_USE_FANCY_MATH_387
17201
   && flag_unsafe_math_optimizations
17202
   && !(reload_completed || reload_in_progress)"
17203
  "#"
17204
  "&& 1"
17205
  [(const_int 0)]
17206
{
17207
  if (memory_operand (operands[0], VOIDmode))
17208
    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17209
  else
17210
    {
17211
      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17212
      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17213
                                         operands[2]));
17214
    }
17215
  DONE;
17216
}
17217
  [(set_attr "type" "fpspc")
17218
   (set_attr "mode" "DI")])
17219
 
17220
(define_insn "fistdi2"
17221
  [(set (match_operand:DI 0 "memory_operand" "=m")
17222
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17223
         UNSPEC_FIST))
17224
   (clobber (match_scratch:XF 2 "=&1f"))]
17225
  "TARGET_USE_FANCY_MATH_387
17226
   && flag_unsafe_math_optimizations"
17227
  "* return output_fix_trunc (insn, operands, 0);"
17228
  [(set_attr "type" "fpspc")
17229
   (set_attr "mode" "DI")])
17230
 
17231
(define_insn "fistdi2_with_temp"
17232
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17233
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17234
         UNSPEC_FIST))
17235
   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17236
   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17237
  "TARGET_USE_FANCY_MATH_387
17238
   && flag_unsafe_math_optimizations"
17239
  "#"
17240
  [(set_attr "type" "fpspc")
17241
   (set_attr "mode" "DI")])
17242
 
17243
(define_split
17244
  [(set (match_operand:DI 0 "register_operand" "")
17245
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17246
         UNSPEC_FIST))
17247
   (clobber (match_operand:DI 2 "memory_operand" ""))
17248
   (clobber (match_scratch 3 ""))]
17249
  "reload_completed"
17250
  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17251
              (clobber (match_dup 3))])
17252
   (set (match_dup 0) (match_dup 2))]
17253
  "")
17254
 
17255
(define_split
17256
  [(set (match_operand:DI 0 "memory_operand" "")
17257
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17258
         UNSPEC_FIST))
17259
   (clobber (match_operand:DI 2 "memory_operand" ""))
17260
   (clobber (match_scratch 3 ""))]
17261
  "reload_completed"
17262
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17263
              (clobber (match_dup 3))])]
17264
  "")
17265
 
17266
(define_insn_and_split "*fist2_1"
17267
  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17268
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17269
         UNSPEC_FIST))]
17270
  "TARGET_USE_FANCY_MATH_387
17271
   && flag_unsafe_math_optimizations
17272
   && !(reload_completed || reload_in_progress)"
17273
  "#"
17274
  "&& 1"
17275
  [(const_int 0)]
17276
{
17277
  operands[2] = assign_386_stack_local (mode, SLOT_TEMP);
17278
  emit_insn (gen_fist2_with_temp (operands[0], operands[1],
17279
                                        operands[2]));
17280
  DONE;
17281
}
17282
  [(set_attr "type" "fpspc")
17283
   (set_attr "mode" "")])
17284
 
17285
(define_insn "fist2"
17286
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17287
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17288
         UNSPEC_FIST))]
17289
  "TARGET_USE_FANCY_MATH_387
17290
   && flag_unsafe_math_optimizations"
17291
  "* return output_fix_trunc (insn, operands, 0);"
17292
  [(set_attr "type" "fpspc")
17293
   (set_attr "mode" "")])
17294
 
17295
(define_insn "fist2_with_temp"
17296
  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17297
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17298
         UNSPEC_FIST))
17299
   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17300
  "TARGET_USE_FANCY_MATH_387
17301
   && flag_unsafe_math_optimizations"
17302
  "#"
17303
  [(set_attr "type" "fpspc")
17304
   (set_attr "mode" "")])
17305
 
17306
(define_split
17307
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17308
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17309
         UNSPEC_FIST))
17310
   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17311
  "reload_completed"
17312
  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17313
                       UNSPEC_FIST))
17314
   (set (match_dup 0) (match_dup 2))]
17315
  "")
17316
 
17317
(define_split
17318
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17319
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17320
         UNSPEC_FIST))
17321
   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17322
  "reload_completed"
17323
  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17324
                       UNSPEC_FIST))]
17325
  "")
17326
 
17327
(define_expand "lrint2"
17328
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17329
        (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17330
         UNSPEC_FIST))]
17331
  "TARGET_USE_FANCY_MATH_387
17332
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17333
   && flag_unsafe_math_optimizations"
17334
  "")
17335
 
17336
;; Rounding mode control word calculation could clobber FLAGS_REG.
17337
(define_insn_and_split "frndintxf2_floor"
17338
  [(set (match_operand:XF 0 "register_operand" "=f")
17339
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17340
         UNSPEC_FRNDINT_FLOOR))
17341
   (clobber (reg:CC FLAGS_REG))]
17342
  "TARGET_USE_FANCY_MATH_387
17343
   && flag_unsafe_math_optimizations
17344
   && !(reload_completed || reload_in_progress)"
17345
  "#"
17346
  "&& 1"
17347
  [(const_int 0)]
17348
{
17349
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17350
 
17351
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17352
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17353
 
17354
  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17355
                                        operands[2], operands[3]));
17356
  DONE;
17357
}
17358
  [(set_attr "type" "frndint")
17359
   (set_attr "i387_cw" "floor")
17360
   (set_attr "mode" "XF")])
17361
 
17362
(define_insn "frndintxf2_floor_i387"
17363
  [(set (match_operand:XF 0 "register_operand" "=f")
17364
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17365
         UNSPEC_FRNDINT_FLOOR))
17366
   (use (match_operand:HI 2 "memory_operand" "m"))
17367
   (use (match_operand:HI 3 "memory_operand" "m"))]
17368
  "TARGET_USE_FANCY_MATH_387
17369
   && flag_unsafe_math_optimizations"
17370
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17371
  [(set_attr "type" "frndint")
17372
   (set_attr "i387_cw" "floor")
17373
   (set_attr "mode" "XF")])
17374
 
17375
(define_expand "floorxf2"
17376
  [(use (match_operand:XF 0 "register_operand" ""))
17377
   (use (match_operand:XF 1 "register_operand" ""))]
17378
  "TARGET_USE_FANCY_MATH_387
17379
   && flag_unsafe_math_optimizations"
17380
{
17381
  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17382
  DONE;
17383
})
17384
 
17385
(define_expand "floordf2"
17386
  [(use (match_operand:DF 0 "register_operand" ""))
17387
   (use (match_operand:DF 1 "register_operand" ""))]
17388
  "TARGET_USE_FANCY_MATH_387
17389
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17390
   && flag_unsafe_math_optimizations"
17391
{
17392
  rtx op0 = gen_reg_rtx (XFmode);
17393
  rtx op1 = gen_reg_rtx (XFmode);
17394
 
17395
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17396
  emit_insn (gen_frndintxf2_floor (op0, op1));
17397
 
17398
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17399
  DONE;
17400
})
17401
 
17402
(define_expand "floorsf2"
17403
  [(use (match_operand:SF 0 "register_operand" ""))
17404
   (use (match_operand:SF 1 "register_operand" ""))]
17405
  "TARGET_USE_FANCY_MATH_387
17406
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17407
   && flag_unsafe_math_optimizations"
17408
{
17409
  rtx op0 = gen_reg_rtx (XFmode);
17410
  rtx op1 = gen_reg_rtx (XFmode);
17411
 
17412
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17413
  emit_insn (gen_frndintxf2_floor (op0, op1));
17414
 
17415
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17416
  DONE;
17417
})
17418
 
17419
(define_insn_and_split "*fist2_floor_1"
17420
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17421
        (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17422
         UNSPEC_FIST_FLOOR))
17423
   (clobber (reg:CC FLAGS_REG))]
17424
  "TARGET_USE_FANCY_MATH_387
17425
   && flag_unsafe_math_optimizations
17426
   && !(reload_completed || reload_in_progress)"
17427
  "#"
17428
  "&& 1"
17429
  [(const_int 0)]
17430
{
17431
  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17432
 
17433
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17434
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17435
  if (memory_operand (operands[0], VOIDmode))
17436
    emit_insn (gen_fist2_floor (operands[0], operands[1],
17437
                                      operands[2], operands[3]));
17438
  else
17439
    {
17440
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
17441
      emit_insn (gen_fist2_floor_with_temp (operands[0], operands[1],
17442
                                                  operands[2], operands[3],
17443
                                                  operands[4]));
17444
    }
17445
  DONE;
17446
}
17447
  [(set_attr "type" "fistp")
17448
   (set_attr "i387_cw" "floor")
17449
   (set_attr "mode" "")])
17450
 
17451
(define_insn "fistdi2_floor"
17452
  [(set (match_operand:DI 0 "memory_operand" "=m")
17453
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17454
         UNSPEC_FIST_FLOOR))
17455
   (use (match_operand:HI 2 "memory_operand" "m"))
17456
   (use (match_operand:HI 3 "memory_operand" "m"))
17457
   (clobber (match_scratch:XF 4 "=&1f"))]
17458
  "TARGET_USE_FANCY_MATH_387
17459
   && flag_unsafe_math_optimizations"
17460
  "* return output_fix_trunc (insn, operands, 0);"
17461
  [(set_attr "type" "fistp")
17462
   (set_attr "i387_cw" "floor")
17463
   (set_attr "mode" "DI")])
17464
 
17465
(define_insn "fistdi2_floor_with_temp"
17466
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17467
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17468
         UNSPEC_FIST_FLOOR))
17469
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17470
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17471
   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17472
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17473
  "TARGET_USE_FANCY_MATH_387
17474
   && flag_unsafe_math_optimizations"
17475
  "#"
17476
  [(set_attr "type" "fistp")
17477
   (set_attr "i387_cw" "floor")
17478
   (set_attr "mode" "DI")])
17479
 
17480
(define_split
17481
  [(set (match_operand:DI 0 "register_operand" "")
17482
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17483
         UNSPEC_FIST_FLOOR))
17484
   (use (match_operand:HI 2 "memory_operand" ""))
17485
   (use (match_operand:HI 3 "memory_operand" ""))
17486
   (clobber (match_operand:DI 4 "memory_operand" ""))
17487
   (clobber (match_scratch 5 ""))]
17488
  "reload_completed"
17489
  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17490
              (use (match_dup 2))
17491
              (use (match_dup 3))
17492
              (clobber (match_dup 5))])
17493
   (set (match_dup 0) (match_dup 4))]
17494
  "")
17495
 
17496
(define_split
17497
  [(set (match_operand:DI 0 "memory_operand" "")
17498
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17499
         UNSPEC_FIST_FLOOR))
17500
   (use (match_operand:HI 2 "memory_operand" ""))
17501
   (use (match_operand:HI 3 "memory_operand" ""))
17502
   (clobber (match_operand:DI 4 "memory_operand" ""))
17503
   (clobber (match_scratch 5 ""))]
17504
  "reload_completed"
17505
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17506
              (use (match_dup 2))
17507
              (use (match_dup 3))
17508
              (clobber (match_dup 5))])]
17509
  "")
17510
 
17511
(define_insn "fist2_floor"
17512
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17513
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17514
         UNSPEC_FIST_FLOOR))
17515
   (use (match_operand:HI 2 "memory_operand" "m"))
17516
   (use (match_operand:HI 3 "memory_operand" "m"))]
17517
  "TARGET_USE_FANCY_MATH_387
17518
   && flag_unsafe_math_optimizations"
17519
  "* return output_fix_trunc (insn, operands, 0);"
17520
  [(set_attr "type" "fistp")
17521
   (set_attr "i387_cw" "floor")
17522
   (set_attr "mode" "")])
17523
 
17524
(define_insn "fist2_floor_with_temp"
17525
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17526
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17527
         UNSPEC_FIST_FLOOR))
17528
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17529
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17530
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17531
  "TARGET_USE_FANCY_MATH_387
17532
   && flag_unsafe_math_optimizations"
17533
  "#"
17534
  [(set_attr "type" "fistp")
17535
   (set_attr "i387_cw" "floor")
17536
   (set_attr "mode" "")])
17537
 
17538
(define_split
17539
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17540
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17541
         UNSPEC_FIST_FLOOR))
17542
   (use (match_operand:HI 2 "memory_operand" ""))
17543
   (use (match_operand:HI 3 "memory_operand" ""))
17544
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17545
  "reload_completed"
17546
  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17547
                                  UNSPEC_FIST_FLOOR))
17548
              (use (match_dup 2))
17549
              (use (match_dup 3))])
17550
   (set (match_dup 0) (match_dup 4))]
17551
  "")
17552
 
17553
(define_split
17554
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17555
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17556
         UNSPEC_FIST_FLOOR))
17557
   (use (match_operand:HI 2 "memory_operand" ""))
17558
   (use (match_operand:HI 3 "memory_operand" ""))
17559
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17560
  "reload_completed"
17561
  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17562
                                  UNSPEC_FIST_FLOOR))
17563
              (use (match_dup 2))
17564
              (use (match_dup 3))])]
17565
  "")
17566
 
17567
(define_expand "lfloor2"
17568
  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17569
                   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17570
                    UNSPEC_FIST_FLOOR))
17571
              (clobber (reg:CC FLAGS_REG))])]
17572
  "TARGET_USE_FANCY_MATH_387
17573
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17574
   && flag_unsafe_math_optimizations"
17575
  "")
17576
 
17577
;; Rounding mode control word calculation could clobber FLAGS_REG.
17578
(define_insn_and_split "frndintxf2_ceil"
17579
  [(set (match_operand:XF 0 "register_operand" "=f")
17580
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17581
         UNSPEC_FRNDINT_CEIL))
17582
   (clobber (reg:CC FLAGS_REG))]
17583
  "TARGET_USE_FANCY_MATH_387
17584
   && flag_unsafe_math_optimizations
17585
   && !(reload_completed || reload_in_progress)"
17586
  "#"
17587
  "&& 1"
17588
  [(const_int 0)]
17589
{
17590
  ix86_optimize_mode_switching[I387_CEIL] = 1;
17591
 
17592
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17593
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17594
 
17595
  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17596
                                       operands[2], operands[3]));
17597
  DONE;
17598
}
17599
  [(set_attr "type" "frndint")
17600
   (set_attr "i387_cw" "ceil")
17601
   (set_attr "mode" "XF")])
17602
 
17603
(define_insn "frndintxf2_ceil_i387"
17604
  [(set (match_operand:XF 0 "register_operand" "=f")
17605
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17606
         UNSPEC_FRNDINT_CEIL))
17607
   (use (match_operand:HI 2 "memory_operand" "m"))
17608
   (use (match_operand:HI 3 "memory_operand" "m"))]
17609
  "TARGET_USE_FANCY_MATH_387
17610
   && flag_unsafe_math_optimizations"
17611
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17612
  [(set_attr "type" "frndint")
17613
   (set_attr "i387_cw" "ceil")
17614
   (set_attr "mode" "XF")])
17615
 
17616
(define_expand "ceilxf2"
17617
  [(use (match_operand:XF 0 "register_operand" ""))
17618
   (use (match_operand:XF 1 "register_operand" ""))]
17619
  "TARGET_USE_FANCY_MATH_387
17620
   && flag_unsafe_math_optimizations"
17621
{
17622
  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17623
  DONE;
17624
})
17625
 
17626
(define_expand "ceildf2"
17627
  [(use (match_operand:DF 0 "register_operand" ""))
17628
   (use (match_operand:DF 1 "register_operand" ""))]
17629
  "TARGET_USE_FANCY_MATH_387
17630
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17631
   && flag_unsafe_math_optimizations"
17632
{
17633
  rtx op0 = gen_reg_rtx (XFmode);
17634
  rtx op1 = gen_reg_rtx (XFmode);
17635
 
17636
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17637
  emit_insn (gen_frndintxf2_ceil (op0, op1));
17638
 
17639
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17640
  DONE;
17641
})
17642
 
17643
(define_expand "ceilsf2"
17644
  [(use (match_operand:SF 0 "register_operand" ""))
17645
   (use (match_operand:SF 1 "register_operand" ""))]
17646
  "TARGET_USE_FANCY_MATH_387
17647
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17648
   && flag_unsafe_math_optimizations"
17649
{
17650
  rtx op0 = gen_reg_rtx (XFmode);
17651
  rtx op1 = gen_reg_rtx (XFmode);
17652
 
17653
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17654
  emit_insn (gen_frndintxf2_ceil (op0, op1));
17655
 
17656
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17657
  DONE;
17658
})
17659
 
17660
(define_insn_and_split "*fist2_ceil_1"
17661
  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17662
        (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17663
         UNSPEC_FIST_CEIL))
17664
   (clobber (reg:CC FLAGS_REG))]
17665
  "TARGET_USE_FANCY_MATH_387
17666
   && flag_unsafe_math_optimizations
17667
   && !(reload_completed || reload_in_progress)"
17668
  "#"
17669
  "&& 1"
17670
  [(const_int 0)]
17671
{
17672
  ix86_optimize_mode_switching[I387_CEIL] = 1;
17673
 
17674
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17675
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17676
  if (memory_operand (operands[0], VOIDmode))
17677
    emit_insn (gen_fist2_ceil (operands[0], operands[1],
17678
                                     operands[2], operands[3]));
17679
  else
17680
    {
17681
      operands[4] = assign_386_stack_local (mode, SLOT_TEMP);
17682
      emit_insn (gen_fist2_ceil_with_temp (operands[0], operands[1],
17683
                                                 operands[2], operands[3],
17684
                                                 operands[4]));
17685
    }
17686
  DONE;
17687
}
17688
  [(set_attr "type" "fistp")
17689
   (set_attr "i387_cw" "ceil")
17690
   (set_attr "mode" "")])
17691
 
17692
(define_insn "fistdi2_ceil"
17693
  [(set (match_operand:DI 0 "memory_operand" "=m")
17694
        (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17695
         UNSPEC_FIST_CEIL))
17696
   (use (match_operand:HI 2 "memory_operand" "m"))
17697
   (use (match_operand:HI 3 "memory_operand" "m"))
17698
   (clobber (match_scratch:XF 4 "=&1f"))]
17699
  "TARGET_USE_FANCY_MATH_387
17700
   && flag_unsafe_math_optimizations"
17701
  "* return output_fix_trunc (insn, operands, 0);"
17702
  [(set_attr "type" "fistp")
17703
   (set_attr "i387_cw" "ceil")
17704
   (set_attr "mode" "DI")])
17705
 
17706
(define_insn "fistdi2_ceil_with_temp"
17707
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17708
        (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17709
         UNSPEC_FIST_CEIL))
17710
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17711
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17712
   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17713
   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17714
  "TARGET_USE_FANCY_MATH_387
17715
   && flag_unsafe_math_optimizations"
17716
  "#"
17717
  [(set_attr "type" "fistp")
17718
   (set_attr "i387_cw" "ceil")
17719
   (set_attr "mode" "DI")])
17720
 
17721
(define_split
17722
  [(set (match_operand:DI 0 "register_operand" "")
17723
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17724
         UNSPEC_FIST_CEIL))
17725
   (use (match_operand:HI 2 "memory_operand" ""))
17726
   (use (match_operand:HI 3 "memory_operand" ""))
17727
   (clobber (match_operand:DI 4 "memory_operand" ""))
17728
   (clobber (match_scratch 5 ""))]
17729
  "reload_completed"
17730
  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17731
              (use (match_dup 2))
17732
              (use (match_dup 3))
17733
              (clobber (match_dup 5))])
17734
   (set (match_dup 0) (match_dup 4))]
17735
  "")
17736
 
17737
(define_split
17738
  [(set (match_operand:DI 0 "memory_operand" "")
17739
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17740
         UNSPEC_FIST_CEIL))
17741
   (use (match_operand:HI 2 "memory_operand" ""))
17742
   (use (match_operand:HI 3 "memory_operand" ""))
17743
   (clobber (match_operand:DI 4 "memory_operand" ""))
17744
   (clobber (match_scratch 5 ""))]
17745
  "reload_completed"
17746
  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17747
              (use (match_dup 2))
17748
              (use (match_dup 3))
17749
              (clobber (match_dup 5))])]
17750
  "")
17751
 
17752
(define_insn "fist2_ceil"
17753
  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17754
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17755
         UNSPEC_FIST_CEIL))
17756
   (use (match_operand:HI 2 "memory_operand" "m"))
17757
   (use (match_operand:HI 3 "memory_operand" "m"))]
17758
  "TARGET_USE_FANCY_MATH_387
17759
   && flag_unsafe_math_optimizations"
17760
  "* return output_fix_trunc (insn, operands, 0);"
17761
  [(set_attr "type" "fistp")
17762
   (set_attr "i387_cw" "ceil")
17763
   (set_attr "mode" "")])
17764
 
17765
(define_insn "fist2_ceil_with_temp"
17766
  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17767
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17768
         UNSPEC_FIST_CEIL))
17769
   (use (match_operand:HI 2 "memory_operand" "m,m"))
17770
   (use (match_operand:HI 3 "memory_operand" "m,m"))
17771
   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17772
  "TARGET_USE_FANCY_MATH_387
17773
   && flag_unsafe_math_optimizations"
17774
  "#"
17775
  [(set_attr "type" "fistp")
17776
   (set_attr "i387_cw" "ceil")
17777
   (set_attr "mode" "")])
17778
 
17779
(define_split
17780
  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17781
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17782
         UNSPEC_FIST_CEIL))
17783
   (use (match_operand:HI 2 "memory_operand" ""))
17784
   (use (match_operand:HI 3 "memory_operand" ""))
17785
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17786
  "reload_completed"
17787
  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17788
                                  UNSPEC_FIST_CEIL))
17789
              (use (match_dup 2))
17790
              (use (match_dup 3))])
17791
   (set (match_dup 0) (match_dup 4))]
17792
  "")
17793
 
17794
(define_split
17795
  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17796
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17797
         UNSPEC_FIST_CEIL))
17798
   (use (match_operand:HI 2 "memory_operand" ""))
17799
   (use (match_operand:HI 3 "memory_operand" ""))
17800
   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17801
  "reload_completed"
17802
  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17803
                                  UNSPEC_FIST_CEIL))
17804
              (use (match_dup 2))
17805
              (use (match_dup 3))])]
17806
  "")
17807
 
17808
(define_expand "lceil2"
17809
  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17810
                   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17811
                    UNSPEC_FIST_CEIL))
17812
              (clobber (reg:CC FLAGS_REG))])]
17813
  "TARGET_USE_FANCY_MATH_387
17814
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17815
   && flag_unsafe_math_optimizations"
17816
  "")
17817
 
17818
;; Rounding mode control word calculation could clobber FLAGS_REG.
17819
(define_insn_and_split "frndintxf2_trunc"
17820
  [(set (match_operand:XF 0 "register_operand" "=f")
17821
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17822
         UNSPEC_FRNDINT_TRUNC))
17823
   (clobber (reg:CC FLAGS_REG))]
17824
  "TARGET_USE_FANCY_MATH_387
17825
   && flag_unsafe_math_optimizations
17826
   && !(reload_completed || reload_in_progress)"
17827
  "#"
17828
  "&& 1"
17829
  [(const_int 0)]
17830
{
17831
  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17832
 
17833
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17834
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17835
 
17836
  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17837
                                        operands[2], operands[3]));
17838
  DONE;
17839
}
17840
  [(set_attr "type" "frndint")
17841
   (set_attr "i387_cw" "trunc")
17842
   (set_attr "mode" "XF")])
17843
 
17844
(define_insn "frndintxf2_trunc_i387"
17845
  [(set (match_operand:XF 0 "register_operand" "=f")
17846
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17847
         UNSPEC_FRNDINT_TRUNC))
17848
   (use (match_operand:HI 2 "memory_operand" "m"))
17849
   (use (match_operand:HI 3 "memory_operand" "m"))]
17850
  "TARGET_USE_FANCY_MATH_387
17851
   && flag_unsafe_math_optimizations"
17852
  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17853
  [(set_attr "type" "frndint")
17854
   (set_attr "i387_cw" "trunc")
17855
   (set_attr "mode" "XF")])
17856
 
17857
(define_expand "btruncxf2"
17858
  [(use (match_operand:XF 0 "register_operand" ""))
17859
   (use (match_operand:XF 1 "register_operand" ""))]
17860
  "TARGET_USE_FANCY_MATH_387
17861
   && flag_unsafe_math_optimizations"
17862
{
17863
  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17864
  DONE;
17865
})
17866
 
17867
(define_expand "btruncdf2"
17868
  [(use (match_operand:DF 0 "register_operand" ""))
17869
   (use (match_operand:DF 1 "register_operand" ""))]
17870
  "TARGET_USE_FANCY_MATH_387
17871
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17872
   && flag_unsafe_math_optimizations"
17873
{
17874
  rtx op0 = gen_reg_rtx (XFmode);
17875
  rtx op1 = gen_reg_rtx (XFmode);
17876
 
17877
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17878
  emit_insn (gen_frndintxf2_trunc (op0, op1));
17879
 
17880
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17881
  DONE;
17882
})
17883
 
17884
(define_expand "btruncsf2"
17885
  [(use (match_operand:SF 0 "register_operand" ""))
17886
   (use (match_operand:SF 1 "register_operand" ""))]
17887
  "TARGET_USE_FANCY_MATH_387
17888
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17889
   && flag_unsafe_math_optimizations"
17890
{
17891
  rtx op0 = gen_reg_rtx (XFmode);
17892
  rtx op1 = gen_reg_rtx (XFmode);
17893
 
17894
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17895
  emit_insn (gen_frndintxf2_trunc (op0, op1));
17896
 
17897
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17898
  DONE;
17899
})
17900
 
17901
;; Rounding mode control word calculation could clobber FLAGS_REG.
17902
(define_insn_and_split "frndintxf2_mask_pm"
17903
  [(set (match_operand:XF 0 "register_operand" "=f")
17904
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17905
         UNSPEC_FRNDINT_MASK_PM))
17906
   (clobber (reg:CC FLAGS_REG))]
17907
  "TARGET_USE_FANCY_MATH_387
17908
   && flag_unsafe_math_optimizations
17909
   && !(reload_completed || reload_in_progress)"
17910
  "#"
17911
  "&& 1"
17912
  [(const_int 0)]
17913
{
17914
  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17915
 
17916
  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17917
  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17918
 
17919
  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17920
                                          operands[2], operands[3]));
17921
  DONE;
17922
}
17923
  [(set_attr "type" "frndint")
17924
   (set_attr "i387_cw" "mask_pm")
17925
   (set_attr "mode" "XF")])
17926
 
17927
(define_insn "frndintxf2_mask_pm_i387"
17928
  [(set (match_operand:XF 0 "register_operand" "=f")
17929
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17930
         UNSPEC_FRNDINT_MASK_PM))
17931
   (use (match_operand:HI 2 "memory_operand" "m"))
17932
   (use (match_operand:HI 3 "memory_operand" "m"))]
17933
  "TARGET_USE_FANCY_MATH_387
17934
   && flag_unsafe_math_optimizations"
17935
  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17936
  [(set_attr "type" "frndint")
17937
   (set_attr "i387_cw" "mask_pm")
17938
   (set_attr "mode" "XF")])
17939
 
17940
(define_expand "nearbyintxf2"
17941
  [(use (match_operand:XF 0 "register_operand" ""))
17942
   (use (match_operand:XF 1 "register_operand" ""))]
17943
  "TARGET_USE_FANCY_MATH_387
17944
   && flag_unsafe_math_optimizations"
17945
{
17946
  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17947
 
17948
  DONE;
17949
})
17950
 
17951
(define_expand "nearbyintdf2"
17952
  [(use (match_operand:DF 0 "register_operand" ""))
17953
   (use (match_operand:DF 1 "register_operand" ""))]
17954
  "TARGET_USE_FANCY_MATH_387
17955
   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17956
   && flag_unsafe_math_optimizations"
17957
{
17958
  rtx op0 = gen_reg_rtx (XFmode);
17959
  rtx op1 = gen_reg_rtx (XFmode);
17960
 
17961
  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17962
  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17963
 
17964
  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17965
  DONE;
17966
})
17967
 
17968
(define_expand "nearbyintsf2"
17969
  [(use (match_operand:SF 0 "register_operand" ""))
17970
   (use (match_operand:SF 1 "register_operand" ""))]
17971
  "TARGET_USE_FANCY_MATH_387
17972
   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17973
   && flag_unsafe_math_optimizations"
17974
{
17975
  rtx op0 = gen_reg_rtx (XFmode);
17976
  rtx op1 = gen_reg_rtx (XFmode);
17977
 
17978
  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17979
  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17980
 
17981
  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17982
  DONE;
17983
})
17984
 
17985
 
17986
;; Block operation instructions
17987
 
17988
(define_insn "cld"
17989
 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17990
 ""
17991
 "cld"
17992
  [(set_attr "type" "cld")])
17993
 
17994
(define_expand "movmemsi"
17995
  [(use (match_operand:BLK 0 "memory_operand" ""))
17996
   (use (match_operand:BLK 1 "memory_operand" ""))
17997
   (use (match_operand:SI 2 "nonmemory_operand" ""))
17998
   (use (match_operand:SI 3 "const_int_operand" ""))]
17999
  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18000
{
18001
 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18002
   DONE;
18003
 else
18004
   FAIL;
18005
})
18006
 
18007
(define_expand "movmemdi"
18008
  [(use (match_operand:BLK 0 "memory_operand" ""))
18009
   (use (match_operand:BLK 1 "memory_operand" ""))
18010
   (use (match_operand:DI 2 "nonmemory_operand" ""))
18011
   (use (match_operand:DI 3 "const_int_operand" ""))]
18012
  "TARGET_64BIT"
18013
{
18014
 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18015
   DONE;
18016
 else
18017
   FAIL;
18018
})
18019
 
18020
;; Most CPUs don't like single string operations
18021
;; Handle this case here to simplify previous expander.
18022
 
18023
(define_expand "strmov"
18024
  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18025
   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18026
   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18027
              (clobber (reg:CC FLAGS_REG))])
18028
   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18029
              (clobber (reg:CC FLAGS_REG))])]
18030
  ""
18031
{
18032
  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18033
 
18034
  /* If .md ever supports :P for Pmode, these can be directly
18035
     in the pattern above.  */
18036
  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18037
  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18038
 
18039
  if (TARGET_SINGLE_STRINGOP || optimize_size)
18040
    {
18041
      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18042
                                      operands[2], operands[3],
18043
                                      operands[5], operands[6]));
18044
      DONE;
18045
    }
18046
 
18047
  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18048
})
18049
 
18050
(define_expand "strmov_singleop"
18051
  [(parallel [(set (match_operand 1 "memory_operand" "")
18052
                   (match_operand 3 "memory_operand" ""))
18053
              (set (match_operand 0 "register_operand" "")
18054
                   (match_operand 4 "" ""))
18055
              (set (match_operand 2 "register_operand" "")
18056
                   (match_operand 5 "" ""))
18057
              (use (reg:SI DIRFLAG_REG))])]
18058
  "TARGET_SINGLE_STRINGOP || optimize_size"
18059
  "")
18060
 
18061
(define_insn "*strmovdi_rex_1"
18062
  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18063
        (mem:DI (match_operand:DI 3 "register_operand" "1")))
18064
   (set (match_operand:DI 0 "register_operand" "=D")
18065
        (plus:DI (match_dup 2)
18066
                 (const_int 8)))
18067
   (set (match_operand:DI 1 "register_operand" "=S")
18068
        (plus:DI (match_dup 3)
18069
                 (const_int 8)))
18070
   (use (reg:SI DIRFLAG_REG))]
18071
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18072
  "movsq"
18073
  [(set_attr "type" "str")
18074
   (set_attr "mode" "DI")
18075
   (set_attr "memory" "both")])
18076
 
18077
(define_insn "*strmovsi_1"
18078
  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18079
        (mem:SI (match_operand:SI 3 "register_operand" "1")))
18080
   (set (match_operand:SI 0 "register_operand" "=D")
18081
        (plus:SI (match_dup 2)
18082
                 (const_int 4)))
18083
   (set (match_operand:SI 1 "register_operand" "=S")
18084
        (plus:SI (match_dup 3)
18085
                 (const_int 4)))
18086
   (use (reg:SI DIRFLAG_REG))]
18087
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18088
  "{movsl|movsd}"
18089
  [(set_attr "type" "str")
18090
   (set_attr "mode" "SI")
18091
   (set_attr "memory" "both")])
18092
 
18093
(define_insn "*strmovsi_rex_1"
18094
  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18095
        (mem:SI (match_operand:DI 3 "register_operand" "1")))
18096
   (set (match_operand:DI 0 "register_operand" "=D")
18097
        (plus:DI (match_dup 2)
18098
                 (const_int 4)))
18099
   (set (match_operand:DI 1 "register_operand" "=S")
18100
        (plus:DI (match_dup 3)
18101
                 (const_int 4)))
18102
   (use (reg:SI DIRFLAG_REG))]
18103
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18104
  "{movsl|movsd}"
18105
  [(set_attr "type" "str")
18106
   (set_attr "mode" "SI")
18107
   (set_attr "memory" "both")])
18108
 
18109
(define_insn "*strmovhi_1"
18110
  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18111
        (mem:HI (match_operand:SI 3 "register_operand" "1")))
18112
   (set (match_operand:SI 0 "register_operand" "=D")
18113
        (plus:SI (match_dup 2)
18114
                 (const_int 2)))
18115
   (set (match_operand:SI 1 "register_operand" "=S")
18116
        (plus:SI (match_dup 3)
18117
                 (const_int 2)))
18118
   (use (reg:SI DIRFLAG_REG))]
18119
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18120
  "movsw"
18121
  [(set_attr "type" "str")
18122
   (set_attr "memory" "both")
18123
   (set_attr "mode" "HI")])
18124
 
18125
(define_insn "*strmovhi_rex_1"
18126
  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18127
        (mem:HI (match_operand:DI 3 "register_operand" "1")))
18128
   (set (match_operand:DI 0 "register_operand" "=D")
18129
        (plus:DI (match_dup 2)
18130
                 (const_int 2)))
18131
   (set (match_operand:DI 1 "register_operand" "=S")
18132
        (plus:DI (match_dup 3)
18133
                 (const_int 2)))
18134
   (use (reg:SI DIRFLAG_REG))]
18135
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18136
  "movsw"
18137
  [(set_attr "type" "str")
18138
   (set_attr "memory" "both")
18139
   (set_attr "mode" "HI")])
18140
 
18141
(define_insn "*strmovqi_1"
18142
  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18143
        (mem:QI (match_operand:SI 3 "register_operand" "1")))
18144
   (set (match_operand:SI 0 "register_operand" "=D")
18145
        (plus:SI (match_dup 2)
18146
                 (const_int 1)))
18147
   (set (match_operand:SI 1 "register_operand" "=S")
18148
        (plus:SI (match_dup 3)
18149
                 (const_int 1)))
18150
   (use (reg:SI DIRFLAG_REG))]
18151
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18152
  "movsb"
18153
  [(set_attr "type" "str")
18154
   (set_attr "memory" "both")
18155
   (set_attr "mode" "QI")])
18156
 
18157
(define_insn "*strmovqi_rex_1"
18158
  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18159
        (mem:QI (match_operand:DI 3 "register_operand" "1")))
18160
   (set (match_operand:DI 0 "register_operand" "=D")
18161
        (plus:DI (match_dup 2)
18162
                 (const_int 1)))
18163
   (set (match_operand:DI 1 "register_operand" "=S")
18164
        (plus:DI (match_dup 3)
18165
                 (const_int 1)))
18166
   (use (reg:SI DIRFLAG_REG))]
18167
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18168
  "movsb"
18169
  [(set_attr "type" "str")
18170
   (set_attr "memory" "both")
18171
   (set_attr "mode" "QI")])
18172
 
18173
(define_expand "rep_mov"
18174
  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18175
              (set (match_operand 0 "register_operand" "")
18176
                   (match_operand 5 "" ""))
18177
              (set (match_operand 2 "register_operand" "")
18178
                   (match_operand 6 "" ""))
18179
              (set (match_operand 1 "memory_operand" "")
18180
                   (match_operand 3 "memory_operand" ""))
18181
              (use (match_dup 4))
18182
              (use (reg:SI DIRFLAG_REG))])]
18183
  ""
18184
  "")
18185
 
18186
(define_insn "*rep_movdi_rex64"
18187
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18188
   (set (match_operand:DI 0 "register_operand" "=D")
18189
        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18190
                            (const_int 3))
18191
                 (match_operand:DI 3 "register_operand" "0")))
18192
   (set (match_operand:DI 1 "register_operand" "=S")
18193
        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18194
                 (match_operand:DI 4 "register_operand" "1")))
18195
   (set (mem:BLK (match_dup 3))
18196
        (mem:BLK (match_dup 4)))
18197
   (use (match_dup 5))
18198
   (use (reg:SI DIRFLAG_REG))]
18199
  "TARGET_64BIT"
18200
  "{rep\;movsq|rep movsq}"
18201
  [(set_attr "type" "str")
18202
   (set_attr "prefix_rep" "1")
18203
   (set_attr "memory" "both")
18204
   (set_attr "mode" "DI")])
18205
 
18206
(define_insn "*rep_movsi"
18207
  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18208
   (set (match_operand:SI 0 "register_operand" "=D")
18209
        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18210
                            (const_int 2))
18211
                 (match_operand:SI 3 "register_operand" "0")))
18212
   (set (match_operand:SI 1 "register_operand" "=S")
18213
        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18214
                 (match_operand:SI 4 "register_operand" "1")))
18215
   (set (mem:BLK (match_dup 3))
18216
        (mem:BLK (match_dup 4)))
18217
   (use (match_dup 5))
18218
   (use (reg:SI DIRFLAG_REG))]
18219
  "!TARGET_64BIT"
18220
  "{rep\;movsl|rep movsd}"
18221
  [(set_attr "type" "str")
18222
   (set_attr "prefix_rep" "1")
18223
   (set_attr "memory" "both")
18224
   (set_attr "mode" "SI")])
18225
 
18226
(define_insn "*rep_movsi_rex64"
18227
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18228
   (set (match_operand:DI 0 "register_operand" "=D")
18229
        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18230
                            (const_int 2))
18231
                 (match_operand:DI 3 "register_operand" "0")))
18232
   (set (match_operand:DI 1 "register_operand" "=S")
18233
        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18234
                 (match_operand:DI 4 "register_operand" "1")))
18235
   (set (mem:BLK (match_dup 3))
18236
        (mem:BLK (match_dup 4)))
18237
   (use (match_dup 5))
18238
   (use (reg:SI DIRFLAG_REG))]
18239
  "TARGET_64BIT"
18240
  "{rep\;movsl|rep movsd}"
18241
  [(set_attr "type" "str")
18242
   (set_attr "prefix_rep" "1")
18243
   (set_attr "memory" "both")
18244
   (set_attr "mode" "SI")])
18245
 
18246
(define_insn "*rep_movqi"
18247
  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18248
   (set (match_operand:SI 0 "register_operand" "=D")
18249
        (plus:SI (match_operand:SI 3 "register_operand" "0")
18250
                 (match_operand:SI 5 "register_operand" "2")))
18251
   (set (match_operand:SI 1 "register_operand" "=S")
18252
        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18253
   (set (mem:BLK (match_dup 3))
18254
        (mem:BLK (match_dup 4)))
18255
   (use (match_dup 5))
18256
   (use (reg:SI DIRFLAG_REG))]
18257
  "!TARGET_64BIT"
18258
  "{rep\;movsb|rep movsb}"
18259
  [(set_attr "type" "str")
18260
   (set_attr "prefix_rep" "1")
18261
   (set_attr "memory" "both")
18262
   (set_attr "mode" "SI")])
18263
 
18264
(define_insn "*rep_movqi_rex64"
18265
  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18266
   (set (match_operand:DI 0 "register_operand" "=D")
18267
        (plus:DI (match_operand:DI 3 "register_operand" "0")
18268
                 (match_operand:DI 5 "register_operand" "2")))
18269
   (set (match_operand:DI 1 "register_operand" "=S")
18270
        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18271
   (set (mem:BLK (match_dup 3))
18272
        (mem:BLK (match_dup 4)))
18273
   (use (match_dup 5))
18274
   (use (reg:SI DIRFLAG_REG))]
18275
  "TARGET_64BIT"
18276
  "{rep\;movsb|rep movsb}"
18277
  [(set_attr "type" "str")
18278
   (set_attr "prefix_rep" "1")
18279
   (set_attr "memory" "both")
18280
   (set_attr "mode" "SI")])
18281
 
18282
(define_expand "setmemsi"
18283
   [(use (match_operand:BLK 0 "memory_operand" ""))
18284
    (use (match_operand:SI 1 "nonmemory_operand" ""))
18285
    (use (match_operand 2 "const_int_operand" ""))
18286
    (use (match_operand 3 "const_int_operand" ""))]
18287
  ""
18288
{
18289
 /* If value to set is not zero, use the library routine.  */
18290
 if (operands[2] != const0_rtx)
18291
   FAIL;
18292
 
18293
 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18294
   DONE;
18295
 else
18296
   FAIL;
18297
})
18298
 
18299
(define_expand "setmemdi"
18300
   [(use (match_operand:BLK 0 "memory_operand" ""))
18301
    (use (match_operand:DI 1 "nonmemory_operand" ""))
18302
    (use (match_operand 2 "const_int_operand" ""))
18303
    (use (match_operand 3 "const_int_operand" ""))]
18304
  "TARGET_64BIT"
18305
{
18306
 /* If value to set is not zero, use the library routine.  */
18307
 if (operands[2] != const0_rtx)
18308
   FAIL;
18309
 
18310
 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18311
   DONE;
18312
 else
18313
   FAIL;
18314
})
18315
 
18316
;; Most CPUs don't like single string operations
18317
;; Handle this case here to simplify previous expander.
18318
 
18319
(define_expand "strset"
18320
  [(set (match_operand 1 "memory_operand" "")
18321
        (match_operand 2 "register_operand" ""))
18322
   (parallel [(set (match_operand 0 "register_operand" "")
18323
                   (match_dup 3))
18324
              (clobber (reg:CC FLAGS_REG))])]
18325
  ""
18326
{
18327
  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18328
    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18329
 
18330
  /* If .md ever supports :P for Pmode, this can be directly
18331
     in the pattern above.  */
18332
  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18333
                              GEN_INT (GET_MODE_SIZE (GET_MODE
18334
                                                      (operands[2]))));
18335
  if (TARGET_SINGLE_STRINGOP || optimize_size)
18336
    {
18337
      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18338
                                      operands[3]));
18339
      DONE;
18340
    }
18341
})
18342
 
18343
(define_expand "strset_singleop"
18344
  [(parallel [(set (match_operand 1 "memory_operand" "")
18345
                   (match_operand 2 "register_operand" ""))
18346
              (set (match_operand 0 "register_operand" "")
18347
                   (match_operand 3 "" ""))
18348
              (use (reg:SI DIRFLAG_REG))])]
18349
  "TARGET_SINGLE_STRINGOP || optimize_size"
18350
  "")
18351
 
18352
(define_insn "*strsetdi_rex_1"
18353
  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18354
        (match_operand:DI 2 "register_operand" "a"))
18355
   (set (match_operand:DI 0 "register_operand" "=D")
18356
        (plus:DI (match_dup 1)
18357
                 (const_int 8)))
18358
   (use (reg:SI DIRFLAG_REG))]
18359
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18360
  "stosq"
18361
  [(set_attr "type" "str")
18362
   (set_attr "memory" "store")
18363
   (set_attr "mode" "DI")])
18364
 
18365
(define_insn "*strsetsi_1"
18366
  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18367
        (match_operand:SI 2 "register_operand" "a"))
18368
   (set (match_operand:SI 0 "register_operand" "=D")
18369
        (plus:SI (match_dup 1)
18370
                 (const_int 4)))
18371
   (use (reg:SI DIRFLAG_REG))]
18372
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373
  "{stosl|stosd}"
18374
  [(set_attr "type" "str")
18375
   (set_attr "memory" "store")
18376
   (set_attr "mode" "SI")])
18377
 
18378
(define_insn "*strsetsi_rex_1"
18379
  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18380
        (match_operand:SI 2 "register_operand" "a"))
18381
   (set (match_operand:DI 0 "register_operand" "=D")
18382
        (plus:DI (match_dup 1)
18383
                 (const_int 4)))
18384
   (use (reg:SI DIRFLAG_REG))]
18385
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18386
  "{stosl|stosd}"
18387
  [(set_attr "type" "str")
18388
   (set_attr "memory" "store")
18389
   (set_attr "mode" "SI")])
18390
 
18391
(define_insn "*strsethi_1"
18392
  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18393
        (match_operand:HI 2 "register_operand" "a"))
18394
   (set (match_operand:SI 0 "register_operand" "=D")
18395
        (plus:SI (match_dup 1)
18396
                 (const_int 2)))
18397
   (use (reg:SI DIRFLAG_REG))]
18398
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399
  "stosw"
18400
  [(set_attr "type" "str")
18401
   (set_attr "memory" "store")
18402
   (set_attr "mode" "HI")])
18403
 
18404
(define_insn "*strsethi_rex_1"
18405
  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18406
        (match_operand:HI 2 "register_operand" "a"))
18407
   (set (match_operand:DI 0 "register_operand" "=D")
18408
        (plus:DI (match_dup 1)
18409
                 (const_int 2)))
18410
   (use (reg:SI DIRFLAG_REG))]
18411
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18412
  "stosw"
18413
  [(set_attr "type" "str")
18414
   (set_attr "memory" "store")
18415
   (set_attr "mode" "HI")])
18416
 
18417
(define_insn "*strsetqi_1"
18418
  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18419
        (match_operand:QI 2 "register_operand" "a"))
18420
   (set (match_operand:SI 0 "register_operand" "=D")
18421
        (plus:SI (match_dup 1)
18422
                 (const_int 1)))
18423
   (use (reg:SI DIRFLAG_REG))]
18424
  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18425
  "stosb"
18426
  [(set_attr "type" "str")
18427
   (set_attr "memory" "store")
18428
   (set_attr "mode" "QI")])
18429
 
18430
(define_insn "*strsetqi_rex_1"
18431
  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18432
        (match_operand:QI 2 "register_operand" "a"))
18433
   (set (match_operand:DI 0 "register_operand" "=D")
18434
        (plus:DI (match_dup 1)
18435
                 (const_int 1)))
18436
   (use (reg:SI DIRFLAG_REG))]
18437
  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18438
  "stosb"
18439
  [(set_attr "type" "str")
18440
   (set_attr "memory" "store")
18441
   (set_attr "mode" "QI")])
18442
 
18443
(define_expand "rep_stos"
18444
  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18445
              (set (match_operand 0 "register_operand" "")
18446
                   (match_operand 4 "" ""))
18447
              (set (match_operand 2 "memory_operand" "") (const_int 0))
18448
              (use (match_operand 3 "register_operand" ""))
18449
              (use (match_dup 1))
18450
              (use (reg:SI DIRFLAG_REG))])]
18451
  ""
18452
  "")
18453
 
18454
(define_insn "*rep_stosdi_rex64"
18455
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18456
   (set (match_operand:DI 0 "register_operand" "=D")
18457
        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18458
                            (const_int 3))
18459
                 (match_operand:DI 3 "register_operand" "0")))
18460
   (set (mem:BLK (match_dup 3))
18461
        (const_int 0))
18462
   (use (match_operand:DI 2 "register_operand" "a"))
18463
   (use (match_dup 4))
18464
   (use (reg:SI DIRFLAG_REG))]
18465
  "TARGET_64BIT"
18466
  "{rep\;stosq|rep stosq}"
18467
  [(set_attr "type" "str")
18468
   (set_attr "prefix_rep" "1")
18469
   (set_attr "memory" "store")
18470
   (set_attr "mode" "DI")])
18471
 
18472
(define_insn "*rep_stossi"
18473
  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18474
   (set (match_operand:SI 0 "register_operand" "=D")
18475
        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18476
                            (const_int 2))
18477
                 (match_operand:SI 3 "register_operand" "0")))
18478
   (set (mem:BLK (match_dup 3))
18479
        (const_int 0))
18480
   (use (match_operand:SI 2 "register_operand" "a"))
18481
   (use (match_dup 4))
18482
   (use (reg:SI DIRFLAG_REG))]
18483
  "!TARGET_64BIT"
18484
  "{rep\;stosl|rep stosd}"
18485
  [(set_attr "type" "str")
18486
   (set_attr "prefix_rep" "1")
18487
   (set_attr "memory" "store")
18488
   (set_attr "mode" "SI")])
18489
 
18490
(define_insn "*rep_stossi_rex64"
18491
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18492
   (set (match_operand:DI 0 "register_operand" "=D")
18493
        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18494
                            (const_int 2))
18495
                 (match_operand:DI 3 "register_operand" "0")))
18496
   (set (mem:BLK (match_dup 3))
18497
        (const_int 0))
18498
   (use (match_operand:SI 2 "register_operand" "a"))
18499
   (use (match_dup 4))
18500
   (use (reg:SI DIRFLAG_REG))]
18501
  "TARGET_64BIT"
18502
  "{rep\;stosl|rep stosd}"
18503
  [(set_attr "type" "str")
18504
   (set_attr "prefix_rep" "1")
18505
   (set_attr "memory" "store")
18506
   (set_attr "mode" "SI")])
18507
 
18508
(define_insn "*rep_stosqi"
18509
  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18510
   (set (match_operand:SI 0 "register_operand" "=D")
18511
        (plus:SI (match_operand:SI 3 "register_operand" "0")
18512
                 (match_operand:SI 4 "register_operand" "1")))
18513
   (set (mem:BLK (match_dup 3))
18514
        (const_int 0))
18515
   (use (match_operand:QI 2 "register_operand" "a"))
18516
   (use (match_dup 4))
18517
   (use (reg:SI DIRFLAG_REG))]
18518
  "!TARGET_64BIT"
18519
  "{rep\;stosb|rep stosb}"
18520
  [(set_attr "type" "str")
18521
   (set_attr "prefix_rep" "1")
18522
   (set_attr "memory" "store")
18523
   (set_attr "mode" "QI")])
18524
 
18525
(define_insn "*rep_stosqi_rex64"
18526
  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18527
   (set (match_operand:DI 0 "register_operand" "=D")
18528
        (plus:DI (match_operand:DI 3 "register_operand" "0")
18529
                 (match_operand:DI 4 "register_operand" "1")))
18530
   (set (mem:BLK (match_dup 3))
18531
        (const_int 0))
18532
   (use (match_operand:QI 2 "register_operand" "a"))
18533
   (use (match_dup 4))
18534
   (use (reg:SI DIRFLAG_REG))]
18535
  "TARGET_64BIT"
18536
  "{rep\;stosb|rep stosb}"
18537
  [(set_attr "type" "str")
18538
   (set_attr "prefix_rep" "1")
18539
   (set_attr "memory" "store")
18540
   (set_attr "mode" "QI")])
18541
 
18542
(define_expand "cmpstrnsi"
18543
  [(set (match_operand:SI 0 "register_operand" "")
18544
        (compare:SI (match_operand:BLK 1 "general_operand" "")
18545
                    (match_operand:BLK 2 "general_operand" "")))
18546
   (use (match_operand 3 "general_operand" ""))
18547
   (use (match_operand 4 "immediate_operand" ""))]
18548
  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18549
{
18550
  rtx addr1, addr2, out, outlow, count, countreg, align;
18551
 
18552
  /* Can't use this if the user has appropriated esi or edi.  */
18553
  if (global_regs[4] || global_regs[5])
18554
    FAIL;
18555
 
18556
  out = operands[0];
18557
  if (GET_CODE (out) != REG)
18558
    out = gen_reg_rtx (SImode);
18559
 
18560
  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18561
  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18562
  if (addr1 != XEXP (operands[1], 0))
18563
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18564
  if (addr2 != XEXP (operands[2], 0))
18565
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18566
 
18567
  count = operands[3];
18568
  countreg = ix86_zero_extend_to_Pmode (count);
18569
 
18570
  /* %%% Iff we are testing strict equality, we can use known alignment
18571
     to good advantage.  This may be possible with combine, particularly
18572
     once cc0 is dead.  */
18573
  align = operands[4];
18574
 
18575
  emit_insn (gen_cld ());
18576
  if (GET_CODE (count) == CONST_INT)
18577
    {
18578
      if (INTVAL (count) == 0)
18579
        {
18580
          emit_move_insn (operands[0], const0_rtx);
18581
          DONE;
18582
        }
18583
      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18584
                                     operands[1], operands[2]));
18585
    }
18586
  else
18587
    {
18588
      if (TARGET_64BIT)
18589
        emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18590
      else
18591
        emit_insn (gen_cmpsi_1 (countreg, countreg));
18592
      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18593
                                  operands[1], operands[2]));
18594
    }
18595
 
18596
  outlow = gen_lowpart (QImode, out);
18597
  emit_insn (gen_cmpintqi (outlow));
18598
  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18599
 
18600
  if (operands[0] != out)
18601
    emit_move_insn (operands[0], out);
18602
 
18603
  DONE;
18604
})
18605
 
18606
;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18607
 
18608
(define_expand "cmpintqi"
18609
  [(set (match_dup 1)
18610
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18611
   (set (match_dup 2)
18612
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18613
   (parallel [(set (match_operand:QI 0 "register_operand" "")
18614
                   (minus:QI (match_dup 1)
18615
                             (match_dup 2)))
18616
              (clobber (reg:CC FLAGS_REG))])]
18617
  ""
18618
  "operands[1] = gen_reg_rtx (QImode);
18619
   operands[2] = gen_reg_rtx (QImode);")
18620
 
18621
;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18622
;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18623
 
18624
(define_expand "cmpstrnqi_nz_1"
18625
  [(parallel [(set (reg:CC FLAGS_REG)
18626
                   (compare:CC (match_operand 4 "memory_operand" "")
18627
                               (match_operand 5 "memory_operand" "")))
18628
              (use (match_operand 2 "register_operand" ""))
18629
              (use (match_operand:SI 3 "immediate_operand" ""))
18630
              (use (reg:SI DIRFLAG_REG))
18631
              (clobber (match_operand 0 "register_operand" ""))
18632
              (clobber (match_operand 1 "register_operand" ""))
18633
              (clobber (match_dup 2))])]
18634
  ""
18635
  "")
18636
 
18637
(define_insn "*cmpstrnqi_nz_1"
18638
  [(set (reg:CC FLAGS_REG)
18639
        (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18640
                    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18641
   (use (match_operand:SI 6 "register_operand" "2"))
18642
   (use (match_operand:SI 3 "immediate_operand" "i"))
18643
   (use (reg:SI DIRFLAG_REG))
18644
   (clobber (match_operand:SI 0 "register_operand" "=S"))
18645
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18646
   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18647
  "!TARGET_64BIT"
18648
  "repz{\;| }cmpsb"
18649
  [(set_attr "type" "str")
18650
   (set_attr "mode" "QI")
18651
   (set_attr "prefix_rep" "1")])
18652
 
18653
(define_insn "*cmpstrnqi_nz_rex_1"
18654
  [(set (reg:CC FLAGS_REG)
18655
        (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18656
                    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18657
   (use (match_operand:DI 6 "register_operand" "2"))
18658
   (use (match_operand:SI 3 "immediate_operand" "i"))
18659
   (use (reg:SI DIRFLAG_REG))
18660
   (clobber (match_operand:DI 0 "register_operand" "=S"))
18661
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18662
   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18663
  "TARGET_64BIT"
18664
  "repz{\;| }cmpsb"
18665
  [(set_attr "type" "str")
18666
   (set_attr "mode" "QI")
18667
   (set_attr "prefix_rep" "1")])
18668
 
18669
;; The same, but the count is not known to not be zero.
18670
 
18671
(define_expand "cmpstrnqi_1"
18672
  [(parallel [(set (reg:CC FLAGS_REG)
18673
                (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18674
                                     (const_int 0))
18675
                  (compare:CC (match_operand 4 "memory_operand" "")
18676
                              (match_operand 5 "memory_operand" ""))
18677
                  (const_int 0)))
18678
              (use (match_operand:SI 3 "immediate_operand" ""))
18679
              (use (reg:CC FLAGS_REG))
18680
              (use (reg:SI DIRFLAG_REG))
18681
              (clobber (match_operand 0 "register_operand" ""))
18682
              (clobber (match_operand 1 "register_operand" ""))
18683
              (clobber (match_dup 2))])]
18684
  ""
18685
  "")
18686
 
18687
(define_insn "*cmpstrnqi_1"
18688
  [(set (reg:CC FLAGS_REG)
18689
        (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18690
                             (const_int 0))
18691
          (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18692
                      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18693
          (const_int 0)))
18694
   (use (match_operand:SI 3 "immediate_operand" "i"))
18695
   (use (reg:CC FLAGS_REG))
18696
   (use (reg:SI DIRFLAG_REG))
18697
   (clobber (match_operand:SI 0 "register_operand" "=S"))
18698
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18699
   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18700
  "!TARGET_64BIT"
18701
  "repz{\;| }cmpsb"
18702
  [(set_attr "type" "str")
18703
   (set_attr "mode" "QI")
18704
   (set_attr "prefix_rep" "1")])
18705
 
18706
(define_insn "*cmpstrnqi_rex_1"
18707
  [(set (reg:CC FLAGS_REG)
18708
        (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18709
                             (const_int 0))
18710
          (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18711
                      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18712
          (const_int 0)))
18713
   (use (match_operand:SI 3 "immediate_operand" "i"))
18714
   (use (reg:CC FLAGS_REG))
18715
   (use (reg:SI DIRFLAG_REG))
18716
   (clobber (match_operand:DI 0 "register_operand" "=S"))
18717
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18718
   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18719
  "TARGET_64BIT"
18720
  "repz{\;| }cmpsb"
18721
  [(set_attr "type" "str")
18722
   (set_attr "mode" "QI")
18723
   (set_attr "prefix_rep" "1")])
18724
 
18725
(define_expand "strlensi"
18726
  [(set (match_operand:SI 0 "register_operand" "")
18727
        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18728
                    (match_operand:QI 2 "immediate_operand" "")
18729
                    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18730
  ""
18731
{
18732
 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18733
   DONE;
18734
 else
18735
   FAIL;
18736
})
18737
 
18738
(define_expand "strlendi"
18739
  [(set (match_operand:DI 0 "register_operand" "")
18740
        (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18741
                    (match_operand:QI 2 "immediate_operand" "")
18742
                    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18743
  ""
18744
{
18745
 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18746
   DONE;
18747
 else
18748
   FAIL;
18749
})
18750
 
18751
(define_expand "strlenqi_1"
18752
  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18753
              (use (reg:SI DIRFLAG_REG))
18754
              (clobber (match_operand 1 "register_operand" ""))
18755
              (clobber (reg:CC FLAGS_REG))])]
18756
  ""
18757
  "")
18758
 
18759
(define_insn "*strlenqi_1"
18760
  [(set (match_operand:SI 0 "register_operand" "=&c")
18761
        (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18762
                    (match_operand:QI 2 "register_operand" "a")
18763
                    (match_operand:SI 3 "immediate_operand" "i")
18764
                    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18765
   (use (reg:SI DIRFLAG_REG))
18766
   (clobber (match_operand:SI 1 "register_operand" "=D"))
18767
   (clobber (reg:CC FLAGS_REG))]
18768
  "!TARGET_64BIT"
18769
  "repnz{\;| }scasb"
18770
  [(set_attr "type" "str")
18771
   (set_attr "mode" "QI")
18772
   (set_attr "prefix_rep" "1")])
18773
 
18774
(define_insn "*strlenqi_rex_1"
18775
  [(set (match_operand:DI 0 "register_operand" "=&c")
18776
        (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18777
                    (match_operand:QI 2 "register_operand" "a")
18778
                    (match_operand:DI 3 "immediate_operand" "i")
18779
                    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18780
   (use (reg:SI DIRFLAG_REG))
18781
   (clobber (match_operand:DI 1 "register_operand" "=D"))
18782
   (clobber (reg:CC FLAGS_REG))]
18783
  "TARGET_64BIT"
18784
  "repnz{\;| }scasb"
18785
  [(set_attr "type" "str")
18786
   (set_attr "mode" "QI")
18787
   (set_attr "prefix_rep" "1")])
18788
 
18789
;; Peephole optimizations to clean up after cmpstrn*.  This should be
18790
;; handled in combine, but it is not currently up to the task.
18791
;; When used for their truth value, the cmpstrn* expanders generate
18792
;; code like this:
18793
;;
18794
;;   repz cmpsb
18795
;;   seta       %al
18796
;;   setb       %dl
18797
;;   cmpb       %al, %dl
18798
;;   jcc        label
18799
;;
18800
;; The intermediate three instructions are unnecessary.
18801
 
18802
;; This one handles cmpstrn*_nz_1...
18803
(define_peephole2
18804
  [(parallel[
18805
     (set (reg:CC FLAGS_REG)
18806
          (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18807
                      (mem:BLK (match_operand 5 "register_operand" ""))))
18808
     (use (match_operand 6 "register_operand" ""))
18809
     (use (match_operand:SI 3 "immediate_operand" ""))
18810
     (use (reg:SI DIRFLAG_REG))
18811
     (clobber (match_operand 0 "register_operand" ""))
18812
     (clobber (match_operand 1 "register_operand" ""))
18813
     (clobber (match_operand 2 "register_operand" ""))])
18814
   (set (match_operand:QI 7 "register_operand" "")
18815
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18816
   (set (match_operand:QI 8 "register_operand" "")
18817
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18818
   (set (reg FLAGS_REG)
18819
        (compare (match_dup 7) (match_dup 8)))
18820
  ]
18821
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18822
  [(parallel[
18823
     (set (reg:CC FLAGS_REG)
18824
          (compare:CC (mem:BLK (match_dup 4))
18825
                      (mem:BLK (match_dup 5))))
18826
     (use (match_dup 6))
18827
     (use (match_dup 3))
18828
     (use (reg:SI DIRFLAG_REG))
18829
     (clobber (match_dup 0))
18830
     (clobber (match_dup 1))
18831
     (clobber (match_dup 2))])]
18832
  "")
18833
 
18834
;; ...and this one handles cmpstrn*_1.
18835
(define_peephole2
18836
  [(parallel[
18837
     (set (reg:CC FLAGS_REG)
18838
          (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18839
                               (const_int 0))
18840
            (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18841
                        (mem:BLK (match_operand 5 "register_operand" "")))
18842
            (const_int 0)))
18843
     (use (match_operand:SI 3 "immediate_operand" ""))
18844
     (use (reg:CC FLAGS_REG))
18845
     (use (reg:SI DIRFLAG_REG))
18846
     (clobber (match_operand 0 "register_operand" ""))
18847
     (clobber (match_operand 1 "register_operand" ""))
18848
     (clobber (match_operand 2 "register_operand" ""))])
18849
   (set (match_operand:QI 7 "register_operand" "")
18850
        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18851
   (set (match_operand:QI 8 "register_operand" "")
18852
        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18853
   (set (reg FLAGS_REG)
18854
        (compare (match_dup 7) (match_dup 8)))
18855
  ]
18856
  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18857
  [(parallel[
18858
     (set (reg:CC FLAGS_REG)
18859
          (if_then_else:CC (ne (match_dup 6)
18860
                               (const_int 0))
18861
            (compare:CC (mem:BLK (match_dup 4))
18862
                        (mem:BLK (match_dup 5)))
18863
            (const_int 0)))
18864
     (use (match_dup 3))
18865
     (use (reg:CC FLAGS_REG))
18866
     (use (reg:SI DIRFLAG_REG))
18867
     (clobber (match_dup 0))
18868
     (clobber (match_dup 1))
18869
     (clobber (match_dup 2))])]
18870
  "")
18871
 
18872
 
18873
 
18874
;; Conditional move instructions.
18875
 
18876
(define_expand "movdicc"
18877
  [(set (match_operand:DI 0 "register_operand" "")
18878
        (if_then_else:DI (match_operand 1 "comparison_operator" "")
18879
                         (match_operand:DI 2 "general_operand" "")
18880
                         (match_operand:DI 3 "general_operand" "")))]
18881
  "TARGET_64BIT"
18882
  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18883
 
18884
(define_insn "x86_movdicc_0_m1_rex64"
18885
  [(set (match_operand:DI 0 "register_operand" "=r")
18886
        (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18887
          (const_int -1)
18888
          (const_int 0)))
18889
   (clobber (reg:CC FLAGS_REG))]
18890
  "TARGET_64BIT"
18891
  "sbb{q}\t%0, %0"
18892
  ; Since we don't have the proper number of operands for an alu insn,
18893
  ; fill in all the blanks.
18894
  [(set_attr "type" "alu")
18895
   (set_attr "pent_pair" "pu")
18896
   (set_attr "memory" "none")
18897
   (set_attr "imm_disp" "false")
18898
   (set_attr "mode" "DI")
18899
   (set_attr "length_immediate" "0")])
18900
 
18901
(define_insn "*movdicc_c_rex64"
18902
  [(set (match_operand:DI 0 "register_operand" "=r,r")
18903
        (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18904
                                [(reg FLAGS_REG) (const_int 0)])
18905
                      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18906
                      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18907
  "TARGET_64BIT && TARGET_CMOVE
18908
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18909
  "@
18910
   cmov%O2%C1\t{%2, %0|%0, %2}
18911
   cmov%O2%c1\t{%3, %0|%0, %3}"
18912
  [(set_attr "type" "icmov")
18913
   (set_attr "mode" "DI")])
18914
 
18915
(define_expand "movsicc"
18916
  [(set (match_operand:SI 0 "register_operand" "")
18917
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
18918
                         (match_operand:SI 2 "general_operand" "")
18919
                         (match_operand:SI 3 "general_operand" "")))]
18920
  ""
18921
  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18922
 
18923
;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18924
;; the register first winds up with `sbbl $0,reg', which is also weird.
18925
;; So just document what we're doing explicitly.
18926
 
18927
(define_insn "x86_movsicc_0_m1"
18928
  [(set (match_operand:SI 0 "register_operand" "=r")
18929
        (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18930
          (const_int -1)
18931
          (const_int 0)))
18932
   (clobber (reg:CC FLAGS_REG))]
18933
  ""
18934
  "sbb{l}\t%0, %0"
18935
  ; Since we don't have the proper number of operands for an alu insn,
18936
  ; fill in all the blanks.
18937
  [(set_attr "type" "alu")
18938
   (set_attr "pent_pair" "pu")
18939
   (set_attr "memory" "none")
18940
   (set_attr "imm_disp" "false")
18941
   (set_attr "mode" "SI")
18942
   (set_attr "length_immediate" "0")])
18943
 
18944
(define_insn "*movsicc_noc"
18945
  [(set (match_operand:SI 0 "register_operand" "=r,r")
18946
        (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18947
                                [(reg FLAGS_REG) (const_int 0)])
18948
                      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18949
                      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18950
  "TARGET_CMOVE
18951
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18952
  "@
18953
   cmov%O2%C1\t{%2, %0|%0, %2}
18954
   cmov%O2%c1\t{%3, %0|%0, %3}"
18955
  [(set_attr "type" "icmov")
18956
   (set_attr "mode" "SI")])
18957
 
18958
(define_expand "movhicc"
18959
  [(set (match_operand:HI 0 "register_operand" "")
18960
        (if_then_else:HI (match_operand 1 "comparison_operator" "")
18961
                         (match_operand:HI 2 "general_operand" "")
18962
                         (match_operand:HI 3 "general_operand" "")))]
18963
  "TARGET_HIMODE_MATH"
18964
  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18965
 
18966
(define_insn "*movhicc_noc"
18967
  [(set (match_operand:HI 0 "register_operand" "=r,r")
18968
        (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18969
                                [(reg FLAGS_REG) (const_int 0)])
18970
                      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18971
                      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18972
  "TARGET_CMOVE
18973
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18974
  "@
18975
   cmov%O2%C1\t{%2, %0|%0, %2}
18976
   cmov%O2%c1\t{%3, %0|%0, %3}"
18977
  [(set_attr "type" "icmov")
18978
   (set_attr "mode" "HI")])
18979
 
18980
(define_expand "movqicc"
18981
  [(set (match_operand:QI 0 "register_operand" "")
18982
        (if_then_else:QI (match_operand 1 "comparison_operator" "")
18983
                         (match_operand:QI 2 "general_operand" "")
18984
                         (match_operand:QI 3 "general_operand" "")))]
18985
  "TARGET_QIMODE_MATH"
18986
  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18987
 
18988
(define_insn_and_split "*movqicc_noc"
18989
  [(set (match_operand:QI 0 "register_operand" "=r,r")
18990
        (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18991
                                [(match_operand 4 "flags_reg_operand" "")
18992
                                 (const_int 0)])
18993
                      (match_operand:QI 2 "register_operand" "r,0")
18994
                      (match_operand:QI 3 "register_operand" "0,r")))]
18995
  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18996
  "#"
18997
  "&& reload_completed"
18998
  [(set (match_dup 0)
18999
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19000
                      (match_dup 2)
19001
                      (match_dup 3)))]
19002
  "operands[0] = gen_lowpart (SImode, operands[0]);
19003
   operands[2] = gen_lowpart (SImode, operands[2]);
19004
   operands[3] = gen_lowpart (SImode, operands[3]);"
19005
  [(set_attr "type" "icmov")
19006
   (set_attr "mode" "SI")])
19007
 
19008
(define_expand "movsfcc"
19009
  [(set (match_operand:SF 0 "register_operand" "")
19010
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
19011
                         (match_operand:SF 2 "register_operand" "")
19012
                         (match_operand:SF 3 "register_operand" "")))]
19013
  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19014
  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19015
 
19016
(define_insn "*movsfcc_1_387"
19017
  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19018
        (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19019
                                [(reg FLAGS_REG) (const_int 0)])
19020
                      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19021
                      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19022
  "TARGET_80387 && TARGET_CMOVE
19023
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19024
  "@
19025
   fcmov%F1\t{%2, %0|%0, %2}
19026
   fcmov%f1\t{%3, %0|%0, %3}
19027
   cmov%O2%C1\t{%2, %0|%0, %2}
19028
   cmov%O2%c1\t{%3, %0|%0, %3}"
19029
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19030
   (set_attr "mode" "SF,SF,SI,SI")])
19031
 
19032
(define_expand "movdfcc"
19033
  [(set (match_operand:DF 0 "register_operand" "")
19034
        (if_then_else:DF (match_operand 1 "comparison_operator" "")
19035
                         (match_operand:DF 2 "register_operand" "")
19036
                         (match_operand:DF 3 "register_operand" "")))]
19037
  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19038
  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19039
 
19040
(define_insn "*movdfcc_1"
19041
  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19042
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19043
                                [(reg FLAGS_REG) (const_int 0)])
19044
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19045
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19046
  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19047
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19048
  "@
19049
   fcmov%F1\t{%2, %0|%0, %2}
19050
   fcmov%f1\t{%3, %0|%0, %3}
19051
   #
19052
   #"
19053
  [(set_attr "type" "fcmov,fcmov,multi,multi")
19054
   (set_attr "mode" "DF")])
19055
 
19056
(define_insn "*movdfcc_1_rex64"
19057
  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19058
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19059
                                [(reg FLAGS_REG) (const_int 0)])
19060
                      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19061
                      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19062
  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19063
   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19064
  "@
19065
   fcmov%F1\t{%2, %0|%0, %2}
19066
   fcmov%f1\t{%3, %0|%0, %3}
19067
   cmov%O2%C1\t{%2, %0|%0, %2}
19068
   cmov%O2%c1\t{%3, %0|%0, %3}"
19069
  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19070
   (set_attr "mode" "DF")])
19071
 
19072
(define_split
19073
  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19074
        (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19075
                                [(match_operand 4 "flags_reg_operand" "")
19076
                                 (const_int 0)])
19077
                      (match_operand:DF 2 "nonimmediate_operand" "")
19078
                      (match_operand:DF 3 "nonimmediate_operand" "")))]
19079
  "!TARGET_64BIT && reload_completed"
19080
  [(set (match_dup 2)
19081
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19082
                      (match_dup 5)
19083
                      (match_dup 7)))
19084
   (set (match_dup 3)
19085
        (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19086
                      (match_dup 6)
19087
                      (match_dup 8)))]
19088
  "split_di (operands+2, 1, operands+5, operands+6);
19089
   split_di (operands+3, 1, operands+7, operands+8);
19090
   split_di (operands, 1, operands+2, operands+3);")
19091
 
19092
(define_expand "movxfcc"
19093
  [(set (match_operand:XF 0 "register_operand" "")
19094
        (if_then_else:XF (match_operand 1 "comparison_operator" "")
19095
                         (match_operand:XF 2 "register_operand" "")
19096
                         (match_operand:XF 3 "register_operand" "")))]
19097
  "TARGET_80387 && TARGET_CMOVE"
19098
  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19099
 
19100
(define_insn "*movxfcc_1"
19101
  [(set (match_operand:XF 0 "register_operand" "=f,f")
19102
        (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19103
                                [(reg FLAGS_REG) (const_int 0)])
19104
                      (match_operand:XF 2 "register_operand" "f,0")
19105
                      (match_operand:XF 3 "register_operand" "0,f")))]
19106
  "TARGET_80387 && TARGET_CMOVE"
19107
  "@
19108
   fcmov%F1\t{%2, %0|%0, %2}
19109
   fcmov%f1\t{%3, %0|%0, %3}"
19110
  [(set_attr "type" "fcmov")
19111
   (set_attr "mode" "XF")])
19112
 
19113
;; These versions of the min/max patterns are intentionally ignorant of
19114
;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19115
;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19116
;; are undefined in this condition, we're certain this is correct.
19117
 
19118
(define_insn "sminsf3"
19119
  [(set (match_operand:SF 0 "register_operand" "=x")
19120
        (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19121
                 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19122
  "TARGET_SSE_MATH"
19123
  "minss\t{%2, %0|%0, %2}"
19124
  [(set_attr "type" "sseadd")
19125
   (set_attr "mode" "SF")])
19126
 
19127
(define_insn "smaxsf3"
19128
  [(set (match_operand:SF 0 "register_operand" "=x")
19129
        (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19130
                 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19131
  "TARGET_SSE_MATH"
19132
  "maxss\t{%2, %0|%0, %2}"
19133
  [(set_attr "type" "sseadd")
19134
   (set_attr "mode" "SF")])
19135
 
19136
(define_insn "smindf3"
19137
  [(set (match_operand:DF 0 "register_operand" "=x")
19138
        (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19139
                 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19140
  "TARGET_SSE2 && TARGET_SSE_MATH"
19141
  "minsd\t{%2, %0|%0, %2}"
19142
  [(set_attr "type" "sseadd")
19143
   (set_attr "mode" "DF")])
19144
 
19145
(define_insn "smaxdf3"
19146
  [(set (match_operand:DF 0 "register_operand" "=x")
19147
        (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19148
                 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19149
  "TARGET_SSE2 && TARGET_SSE_MATH"
19150
  "maxsd\t{%2, %0|%0, %2}"
19151
  [(set_attr "type" "sseadd")
19152
   (set_attr "mode" "DF")])
19153
 
19154
;; These versions of the min/max patterns implement exactly the operations
19155
;;   min = (op1 < op2 ? op1 : op2)
19156
;;   max = (!(op1 < op2) ? op1 : op2)
19157
;; Their operands are not commutative, and thus they may be used in the
19158
;; presence of -0.0 and NaN.
19159
 
19160
(define_insn "*ieee_sminsf3"
19161
  [(set (match_operand:SF 0 "register_operand" "=x")
19162
        (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19163
                    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19164
                   UNSPEC_IEEE_MIN))]
19165
  "TARGET_SSE_MATH"
19166
  "minss\t{%2, %0|%0, %2}"
19167
  [(set_attr "type" "sseadd")
19168
   (set_attr "mode" "SF")])
19169
 
19170
(define_insn "*ieee_smaxsf3"
19171
  [(set (match_operand:SF 0 "register_operand" "=x")
19172
        (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19173
                    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19174
                   UNSPEC_IEEE_MAX))]
19175
  "TARGET_SSE_MATH"
19176
  "maxss\t{%2, %0|%0, %2}"
19177
  [(set_attr "type" "sseadd")
19178
   (set_attr "mode" "SF")])
19179
 
19180
(define_insn "*ieee_smindf3"
19181
  [(set (match_operand:DF 0 "register_operand" "=x")
19182
        (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19183
                    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19184
                   UNSPEC_IEEE_MIN))]
19185
  "TARGET_SSE2 && TARGET_SSE_MATH"
19186
  "minsd\t{%2, %0|%0, %2}"
19187
  [(set_attr "type" "sseadd")
19188
   (set_attr "mode" "DF")])
19189
 
19190
(define_insn "*ieee_smaxdf3"
19191
  [(set (match_operand:DF 0 "register_operand" "=x")
19192
        (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19193
                    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19194
                   UNSPEC_IEEE_MAX))]
19195
  "TARGET_SSE2 && TARGET_SSE_MATH"
19196
  "maxsd\t{%2, %0|%0, %2}"
19197
  [(set_attr "type" "sseadd")
19198
   (set_attr "mode" "DF")])
19199
 
19200
;; Make two stack loads independent:
19201
;;   fld aa              fld aa
19202
;;   fld %st(0)     ->   fld bb
19203
;;   fmul bb             fmul %st(1), %st
19204
;;
19205
;; Actually we only match the last two instructions for simplicity.
19206
(define_peephole2
19207
  [(set (match_operand 0 "fp_register_operand" "")
19208
        (match_operand 1 "fp_register_operand" ""))
19209
   (set (match_dup 0)
19210
        (match_operator 2 "binary_fp_operator"
19211
           [(match_dup 0)
19212
            (match_operand 3 "memory_operand" "")]))]
19213
  "REGNO (operands[0]) != REGNO (operands[1])"
19214
  [(set (match_dup 0) (match_dup 3))
19215
   (set (match_dup 0) (match_dup 4))]
19216
 
19217
  ;; The % modifier is not operational anymore in peephole2's, so we have to
19218
  ;; swap the operands manually in the case of addition and multiplication.
19219
  "if (COMMUTATIVE_ARITH_P (operands[2]))
19220
     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19221
                                 operands[0], operands[1]);
19222
   else
19223
     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19224
                                 operands[1], operands[0]);")
19225
 
19226
;; Conditional addition patterns
19227
(define_expand "addqicc"
19228
  [(match_operand:QI 0 "register_operand" "")
19229
   (match_operand 1 "comparison_operator" "")
19230
   (match_operand:QI 2 "register_operand" "")
19231
   (match_operand:QI 3 "const_int_operand" "")]
19232
  ""
19233
  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19234
 
19235
(define_expand "addhicc"
19236
  [(match_operand:HI 0 "register_operand" "")
19237
   (match_operand 1 "comparison_operator" "")
19238
   (match_operand:HI 2 "register_operand" "")
19239
   (match_operand:HI 3 "const_int_operand" "")]
19240
  ""
19241
  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19242
 
19243
(define_expand "addsicc"
19244
  [(match_operand:SI 0 "register_operand" "")
19245
   (match_operand 1 "comparison_operator" "")
19246
   (match_operand:SI 2 "register_operand" "")
19247
   (match_operand:SI 3 "const_int_operand" "")]
19248
  ""
19249
  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19250
 
19251
(define_expand "adddicc"
19252
  [(match_operand:DI 0 "register_operand" "")
19253
   (match_operand 1 "comparison_operator" "")
19254
   (match_operand:DI 2 "register_operand" "")
19255
   (match_operand:DI 3 "const_int_operand" "")]
19256
  "TARGET_64BIT"
19257
  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19258
 
19259
 
19260
;; Misc patterns (?)
19261
 
19262
;; This pattern exists to put a dependency on all ebp-based memory accesses.
19263
;; Otherwise there will be nothing to keep
19264
;;
19265
;; [(set (reg ebp) (reg esp))]
19266
;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19267
;;  (clobber (eflags)]
19268
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19269
;;
19270
;; in proper program order.
19271
(define_insn "pro_epilogue_adjust_stack_1"
19272
  [(set (match_operand:SI 0 "register_operand" "=r,r")
19273
        (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19274
                 (match_operand:SI 2 "immediate_operand" "i,i")))
19275
   (clobber (reg:CC FLAGS_REG))
19276
   (clobber (mem:BLK (scratch)))]
19277
  "!TARGET_64BIT"
19278
{
19279
  switch (get_attr_type (insn))
19280
    {
19281
    case TYPE_IMOV:
19282
      return "mov{l}\t{%1, %0|%0, %1}";
19283
 
19284
    case TYPE_ALU:
19285
      if (GET_CODE (operands[2]) == CONST_INT
19286
          && (INTVAL (operands[2]) == 128
19287
              || (INTVAL (operands[2]) < 0
19288
                  && INTVAL (operands[2]) != -128)))
19289
        {
19290
          operands[2] = GEN_INT (-INTVAL (operands[2]));
19291
          return "sub{l}\t{%2, %0|%0, %2}";
19292
        }
19293
      return "add{l}\t{%2, %0|%0, %2}";
19294
 
19295
    case TYPE_LEA:
19296
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19297
      return "lea{l}\t{%a2, %0|%0, %a2}";
19298
 
19299
    default:
19300
      gcc_unreachable ();
19301
    }
19302
}
19303
  [(set (attr "type")
19304
        (cond [(eq_attr "alternative" "0")
19305
                 (const_string "alu")
19306
               (match_operand:SI 2 "const0_operand" "")
19307
                 (const_string "imov")
19308
              ]
19309
              (const_string "lea")))
19310
   (set_attr "mode" "SI")])
19311
 
19312
(define_insn "pro_epilogue_adjust_stack_rex64"
19313
  [(set (match_operand:DI 0 "register_operand" "=r,r")
19314
        (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19315
                 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19316
   (clobber (reg:CC FLAGS_REG))
19317
   (clobber (mem:BLK (scratch)))]
19318
  "TARGET_64BIT"
19319
{
19320
  switch (get_attr_type (insn))
19321
    {
19322
    case TYPE_IMOV:
19323
      return "mov{q}\t{%1, %0|%0, %1}";
19324
 
19325
    case TYPE_ALU:
19326
      if (GET_CODE (operands[2]) == CONST_INT
19327
          /* Avoid overflows.  */
19328
          && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19329
          && (INTVAL (operands[2]) == 128
19330
              || (INTVAL (operands[2]) < 0
19331
                  && INTVAL (operands[2]) != -128)))
19332
        {
19333
          operands[2] = GEN_INT (-INTVAL (operands[2]));
19334
          return "sub{q}\t{%2, %0|%0, %2}";
19335
        }
19336
      return "add{q}\t{%2, %0|%0, %2}";
19337
 
19338
    case TYPE_LEA:
19339
      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19340
      return "lea{q}\t{%a2, %0|%0, %a2}";
19341
 
19342
    default:
19343
      gcc_unreachable ();
19344
    }
19345
}
19346
  [(set (attr "type")
19347
        (cond [(eq_attr "alternative" "0")
19348
                 (const_string "alu")
19349
               (match_operand:DI 2 "const0_operand" "")
19350
                 (const_string "imov")
19351
              ]
19352
              (const_string "lea")))
19353
   (set_attr "mode" "DI")])
19354
 
19355
(define_insn "pro_epilogue_adjust_stack_rex64_2"
19356
  [(set (match_operand:DI 0 "register_operand" "=r,r")
19357
        (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19358
                 (match_operand:DI 3 "immediate_operand" "i,i")))
19359
   (use (match_operand:DI 2 "register_operand" "r,r"))
19360
   (clobber (reg:CC FLAGS_REG))
19361
   (clobber (mem:BLK (scratch)))]
19362
  "TARGET_64BIT"
19363
{
19364
  switch (get_attr_type (insn))
19365
    {
19366
    case TYPE_ALU:
19367
      return "add{q}\t{%2, %0|%0, %2}";
19368
 
19369
    case TYPE_LEA:
19370
      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19371
      return "lea{q}\t{%a2, %0|%0, %a2}";
19372
 
19373
    default:
19374
      gcc_unreachable ();
19375
    }
19376
}
19377
  [(set_attr "type" "alu,lea")
19378
   (set_attr "mode" "DI")])
19379
 
19380
(define_expand "allocate_stack_worker"
19381
  [(match_operand:SI 0 "register_operand" "")]
19382
  "TARGET_STACK_PROBE"
19383
{
19384
  if (reload_completed)
19385
    {
19386
      if (TARGET_64BIT)
19387
        emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19388
      else
19389
        emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19390
    }
19391
  else
19392
    {
19393
      if (TARGET_64BIT)
19394
        emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19395
      else
19396
        emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19397
    }
19398
  DONE;
19399
})
19400
 
19401
(define_insn "allocate_stack_worker_1"
19402
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19403
    UNSPECV_STACK_PROBE)
19404
   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19405
   (clobber (match_scratch:SI 1 "=0"))
19406
   (clobber (reg:CC FLAGS_REG))]
19407
  "!TARGET_64BIT && TARGET_STACK_PROBE"
19408
  "call\t__alloca"
19409
  [(set_attr "type" "multi")
19410
   (set_attr "length" "5")])
19411
 
19412
(define_expand "allocate_stack_worker_postreload"
19413
  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19414
                                    UNSPECV_STACK_PROBE)
19415
              (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19416
              (clobber (match_dup 0))
19417
              (clobber (reg:CC FLAGS_REG))])]
19418
  ""
19419
  "")
19420
 
19421
(define_insn "allocate_stack_worker_rex64"
19422
  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19423
    UNSPECV_STACK_PROBE)
19424
   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19425
   (clobber (match_scratch:DI 1 "=0"))
19426
   (clobber (reg:CC FLAGS_REG))]
19427
  "TARGET_64BIT && TARGET_STACK_PROBE"
19428
  "call\t__alloca"
19429
  [(set_attr "type" "multi")
19430
   (set_attr "length" "5")])
19431
 
19432
(define_expand "allocate_stack_worker_rex64_postreload"
19433
  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19434
                                    UNSPECV_STACK_PROBE)
19435
              (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19436
              (clobber (match_dup 0))
19437
              (clobber (reg:CC FLAGS_REG))])]
19438
  ""
19439
  "")
19440
 
19441
(define_expand "allocate_stack"
19442
  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19443
                   (minus:SI (reg:SI SP_REG)
19444
                             (match_operand:SI 1 "general_operand" "")))
19445
              (clobber (reg:CC FLAGS_REG))])
19446
   (parallel [(set (reg:SI SP_REG)
19447
                   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19448
              (clobber (reg:CC FLAGS_REG))])]
19449
  "TARGET_STACK_PROBE"
19450
{
19451
#ifdef CHECK_STACK_LIMIT
19452
  if (GET_CODE (operands[1]) == CONST_INT
19453
      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19454
    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19455
                           operands[1]));
19456
  else
19457
#endif
19458
    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19459
                                                            operands[1])));
19460
 
19461
  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19462
  DONE;
19463
})
19464
 
19465
(define_expand "builtin_setjmp_receiver"
19466
  [(label_ref (match_operand 0 "" ""))]
19467
  "!TARGET_64BIT && flag_pic"
19468
{
19469
  if (TARGET_MACHO)
19470
    {
19471
      rtx xops[3];
19472
      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19473
      rtx label_rtx = gen_label_rtx ();
19474
      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19475
      xops[0] = xops[1] = picreg;
19476
      xops[2] = gen_rtx_CONST (SImode,
19477
                  gen_rtx_MINUS (SImode,
19478
                    gen_rtx_LABEL_REF (SImode, label_rtx),
19479
                    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19480
      ix86_expand_binary_operator (MINUS, SImode, xops);
19481
    }
19482
  else
19483
    emit_insn (gen_set_got (pic_offset_table_rtx));
19484
  DONE;
19485
})
19486
 
19487
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19488
 
19489
(define_split
19490
  [(set (match_operand 0 "register_operand" "")
19491
        (match_operator 3 "promotable_binary_operator"
19492
           [(match_operand 1 "register_operand" "")
19493
            (match_operand 2 "aligned_operand" "")]))
19494
   (clobber (reg:CC FLAGS_REG))]
19495
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19496
   && ((GET_MODE (operands[0]) == HImode
19497
        && ((!optimize_size && !TARGET_FAST_PREFIX)
19498
            /* ??? next two lines just !satisfies_constraint_K (...) */
19499
            || GET_CODE (operands[2]) != CONST_INT
19500
            || satisfies_constraint_K (operands[2])))
19501
       || (GET_MODE (operands[0]) == QImode
19502
           && (TARGET_PROMOTE_QImode || optimize_size)))"
19503
  [(parallel [(set (match_dup 0)
19504
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19505
              (clobber (reg:CC FLAGS_REG))])]
19506
  "operands[0] = gen_lowpart (SImode, operands[0]);
19507
   operands[1] = gen_lowpart (SImode, operands[1]);
19508
   if (GET_CODE (operands[3]) != ASHIFT)
19509
     operands[2] = gen_lowpart (SImode, operands[2]);
19510
   PUT_MODE (operands[3], SImode);")
19511
 
19512
; Promote the QImode tests, as i386 has encoding of the AND
19513
; instruction with 32-bit sign-extended immediate and thus the
19514
; instruction size is unchanged, except in the %eax case for
19515
; which it is increased by one byte, hence the ! optimize_size.
19516
(define_split
19517
  [(set (match_operand 0 "flags_reg_operand" "")
19518
        (match_operator 2 "compare_operator"
19519
          [(and (match_operand 3 "aligned_operand" "")
19520
                (match_operand 4 "const_int_operand" ""))
19521
           (const_int 0)]))
19522
   (set (match_operand 1 "register_operand" "")
19523
        (and (match_dup 3) (match_dup 4)))]
19524
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19525
   /* Ensure that the operand will remain sign-extended immediate.  */
19526
   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19527
   && ! optimize_size
19528
   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19529
       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19530
  [(parallel [(set (match_dup 0)
19531
                   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19532
                                    (const_int 0)]))
19533
              (set (match_dup 1)
19534
                   (and:SI (match_dup 3) (match_dup 4)))])]
19535
{
19536
  operands[4]
19537
    = gen_int_mode (INTVAL (operands[4])
19538
                    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19539
  operands[1] = gen_lowpart (SImode, operands[1]);
19540
  operands[3] = gen_lowpart (SImode, operands[3]);
19541
})
19542
 
19543
; Don't promote the QImode tests, as i386 doesn't have encoding of
19544
; the TEST instruction with 32-bit sign-extended immediate and thus
19545
; the instruction size would at least double, which is not what we
19546
; want even with ! optimize_size.
19547
(define_split
19548
  [(set (match_operand 0 "flags_reg_operand" "")
19549
        (match_operator 1 "compare_operator"
19550
          [(and (match_operand:HI 2 "aligned_operand" "")
19551
                (match_operand:HI 3 "const_int_operand" ""))
19552
           (const_int 0)]))]
19553
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19554
   /* Ensure that the operand will remain sign-extended immediate.  */
19555
   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19556
   && ! TARGET_FAST_PREFIX
19557
   && ! optimize_size"
19558
  [(set (match_dup 0)
19559
        (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19560
                         (const_int 0)]))]
19561
{
19562
  operands[3]
19563
    = gen_int_mode (INTVAL (operands[3])
19564
                    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19565
  operands[2] = gen_lowpart (SImode, operands[2]);
19566
})
19567
 
19568
(define_split
19569
  [(set (match_operand 0 "register_operand" "")
19570
        (neg (match_operand 1 "register_operand" "")))
19571
   (clobber (reg:CC FLAGS_REG))]
19572
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19573
   && (GET_MODE (operands[0]) == HImode
19574
       || (GET_MODE (operands[0]) == QImode
19575
           && (TARGET_PROMOTE_QImode || optimize_size)))"
19576
  [(parallel [(set (match_dup 0)
19577
                   (neg:SI (match_dup 1)))
19578
              (clobber (reg:CC FLAGS_REG))])]
19579
  "operands[0] = gen_lowpart (SImode, operands[0]);
19580
   operands[1] = gen_lowpart (SImode, operands[1]);")
19581
 
19582
(define_split
19583
  [(set (match_operand 0 "register_operand" "")
19584
        (not (match_operand 1 "register_operand" "")))]
19585
  "! TARGET_PARTIAL_REG_STALL && reload_completed
19586
   && (GET_MODE (operands[0]) == HImode
19587
       || (GET_MODE (operands[0]) == QImode
19588
           && (TARGET_PROMOTE_QImode || optimize_size)))"
19589
  [(set (match_dup 0)
19590
        (not:SI (match_dup 1)))]
19591
  "operands[0] = gen_lowpart (SImode, operands[0]);
19592
   operands[1] = gen_lowpart (SImode, operands[1]);")
19593
 
19594
(define_split
19595
  [(set (match_operand 0 "register_operand" "")
19596
        (if_then_else (match_operator 1 "comparison_operator"
19597
                                [(reg FLAGS_REG) (const_int 0)])
19598
                      (match_operand 2 "register_operand" "")
19599
                      (match_operand 3 "register_operand" "")))]
19600
  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19601
   && (GET_MODE (operands[0]) == HImode
19602
       || (GET_MODE (operands[0]) == QImode
19603
           && (TARGET_PROMOTE_QImode || optimize_size)))"
19604
  [(set (match_dup 0)
19605
        (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19606
  "operands[0] = gen_lowpart (SImode, operands[0]);
19607
   operands[2] = gen_lowpart (SImode, operands[2]);
19608
   operands[3] = gen_lowpart (SImode, operands[3]);")
19609
 
19610
 
19611
;; RTL Peephole optimizations, run before sched2.  These primarily look to
19612
;; transform a complex memory operation into two memory to register operations.
19613
 
19614
;; Don't push memory operands
19615
(define_peephole2
19616
  [(set (match_operand:SI 0 "push_operand" "")
19617
        (match_operand:SI 1 "memory_operand" ""))
19618
   (match_scratch:SI 2 "r")]
19619
  "!optimize_size && !TARGET_PUSH_MEMORY
19620
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19621
  [(set (match_dup 2) (match_dup 1))
19622
   (set (match_dup 0) (match_dup 2))]
19623
  "")
19624
 
19625
(define_peephole2
19626
  [(set (match_operand:DI 0 "push_operand" "")
19627
        (match_operand:DI 1 "memory_operand" ""))
19628
   (match_scratch:DI 2 "r")]
19629
  "!optimize_size && !TARGET_PUSH_MEMORY
19630
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19631
  [(set (match_dup 2) (match_dup 1))
19632
   (set (match_dup 0) (match_dup 2))]
19633
  "")
19634
 
19635
;; We need to handle SFmode only, because DFmode and XFmode is split to
19636
;; SImode pushes.
19637
(define_peephole2
19638
  [(set (match_operand:SF 0 "push_operand" "")
19639
        (match_operand:SF 1 "memory_operand" ""))
19640
   (match_scratch:SF 2 "r")]
19641
  "!optimize_size && !TARGET_PUSH_MEMORY
19642
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19643
  [(set (match_dup 2) (match_dup 1))
19644
   (set (match_dup 0) (match_dup 2))]
19645
  "")
19646
 
19647
(define_peephole2
19648
  [(set (match_operand:HI 0 "push_operand" "")
19649
        (match_operand:HI 1 "memory_operand" ""))
19650
   (match_scratch:HI 2 "r")]
19651
  "!optimize_size && !TARGET_PUSH_MEMORY
19652
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19653
  [(set (match_dup 2) (match_dup 1))
19654
   (set (match_dup 0) (match_dup 2))]
19655
  "")
19656
 
19657
(define_peephole2
19658
  [(set (match_operand:QI 0 "push_operand" "")
19659
        (match_operand:QI 1 "memory_operand" ""))
19660
   (match_scratch:QI 2 "q")]
19661
  "!optimize_size && !TARGET_PUSH_MEMORY
19662
   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19663
  [(set (match_dup 2) (match_dup 1))
19664
   (set (match_dup 0) (match_dup 2))]
19665
  "")
19666
 
19667
;; Don't move an immediate directly to memory when the instruction
19668
;; gets too big.
19669
(define_peephole2
19670
  [(match_scratch:SI 1 "r")
19671
   (set (match_operand:SI 0 "memory_operand" "")
19672
        (const_int 0))]
19673
  "! optimize_size
19674
   && ! TARGET_USE_MOV0
19675
   && TARGET_SPLIT_LONG_MOVES
19676
   && get_attr_length (insn) >= ix86_cost->large_insn
19677
   && peep2_regno_dead_p (0, FLAGS_REG)"
19678
  [(parallel [(set (match_dup 1) (const_int 0))
19679
              (clobber (reg:CC FLAGS_REG))])
19680
   (set (match_dup 0) (match_dup 1))]
19681
  "")
19682
 
19683
(define_peephole2
19684
  [(match_scratch:HI 1 "r")
19685
   (set (match_operand:HI 0 "memory_operand" "")
19686
        (const_int 0))]
19687
  "! optimize_size
19688
   && ! TARGET_USE_MOV0
19689
   && TARGET_SPLIT_LONG_MOVES
19690
   && get_attr_length (insn) >= ix86_cost->large_insn
19691
   && peep2_regno_dead_p (0, FLAGS_REG)"
19692
  [(parallel [(set (match_dup 2) (const_int 0))
19693
              (clobber (reg:CC FLAGS_REG))])
19694
   (set (match_dup 0) (match_dup 1))]
19695
  "operands[2] = gen_lowpart (SImode, operands[1]);")
19696
 
19697
(define_peephole2
19698
  [(match_scratch:QI 1 "q")
19699
   (set (match_operand:QI 0 "memory_operand" "")
19700
        (const_int 0))]
19701
  "! optimize_size
19702
   && ! TARGET_USE_MOV0
19703
   && TARGET_SPLIT_LONG_MOVES
19704
   && get_attr_length (insn) >= ix86_cost->large_insn
19705
   && peep2_regno_dead_p (0, FLAGS_REG)"
19706
  [(parallel [(set (match_dup 2) (const_int 0))
19707
              (clobber (reg:CC FLAGS_REG))])
19708
   (set (match_dup 0) (match_dup 1))]
19709
  "operands[2] = gen_lowpart (SImode, operands[1]);")
19710
 
19711
(define_peephole2
19712
  [(match_scratch:SI 2 "r")
19713
   (set (match_operand:SI 0 "memory_operand" "")
19714
        (match_operand:SI 1 "immediate_operand" ""))]
19715
  "! optimize_size
19716
   && get_attr_length (insn) >= ix86_cost->large_insn
19717
   && TARGET_SPLIT_LONG_MOVES"
19718
  [(set (match_dup 2) (match_dup 1))
19719
   (set (match_dup 0) (match_dup 2))]
19720
  "")
19721
 
19722
(define_peephole2
19723
  [(match_scratch:HI 2 "r")
19724
   (set (match_operand:HI 0 "memory_operand" "")
19725
        (match_operand:HI 1 "immediate_operand" ""))]
19726
  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19727
  && TARGET_SPLIT_LONG_MOVES"
19728
  [(set (match_dup 2) (match_dup 1))
19729
   (set (match_dup 0) (match_dup 2))]
19730
  "")
19731
 
19732
(define_peephole2
19733
  [(match_scratch:QI 2 "q")
19734
   (set (match_operand:QI 0 "memory_operand" "")
19735
        (match_operand:QI 1 "immediate_operand" ""))]
19736
  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19737
  && TARGET_SPLIT_LONG_MOVES"
19738
  [(set (match_dup 2) (match_dup 1))
19739
   (set (match_dup 0) (match_dup 2))]
19740
  "")
19741
 
19742
;; Don't compare memory with zero, load and use a test instead.
19743
(define_peephole2
19744
  [(set (match_operand 0 "flags_reg_operand" "")
19745
        (match_operator 1 "compare_operator"
19746
          [(match_operand:SI 2 "memory_operand" "")
19747
           (const_int 0)]))
19748
   (match_scratch:SI 3 "r")]
19749
  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19750
  [(set (match_dup 3) (match_dup 2))
19751
   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19752
  "")
19753
 
19754
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19755
;; Don't split NOTs with a displacement operand, because resulting XOR
19756
;; will not be pairable anyway.
19757
;;
19758
;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19759
;; represented using a modRM byte.  The XOR replacement is long decoded,
19760
;; so this split helps here as well.
19761
;;
19762
;; Note: Can't do this as a regular split because we can't get proper
19763
;; lifetime information then.
19764
 
19765
(define_peephole2
19766
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19767
        (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19768
  "!optimize_size
19769
   && peep2_regno_dead_p (0, FLAGS_REG)
19770
   && ((TARGET_PENTIUM
19771
        && (GET_CODE (operands[0]) != MEM
19772
            || !memory_displacement_operand (operands[0], SImode)))
19773
       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19774
  [(parallel [(set (match_dup 0)
19775
                   (xor:SI (match_dup 1) (const_int -1)))
19776
              (clobber (reg:CC FLAGS_REG))])]
19777
  "")
19778
 
19779
(define_peephole2
19780
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19781
        (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19782
  "!optimize_size
19783
   && peep2_regno_dead_p (0, FLAGS_REG)
19784
   && ((TARGET_PENTIUM
19785
        && (GET_CODE (operands[0]) != MEM
19786
            || !memory_displacement_operand (operands[0], HImode)))
19787
       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19788
  [(parallel [(set (match_dup 0)
19789
                   (xor:HI (match_dup 1) (const_int -1)))
19790
              (clobber (reg:CC FLAGS_REG))])]
19791
  "")
19792
 
19793
(define_peephole2
19794
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19795
        (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19796
  "!optimize_size
19797
   && peep2_regno_dead_p (0, FLAGS_REG)
19798
   && ((TARGET_PENTIUM
19799
        && (GET_CODE (operands[0]) != MEM
19800
            || !memory_displacement_operand (operands[0], QImode)))
19801
       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19802
  [(parallel [(set (match_dup 0)
19803
                   (xor:QI (match_dup 1) (const_int -1)))
19804
              (clobber (reg:CC FLAGS_REG))])]
19805
  "")
19806
 
19807
;; Non pairable "test imm, reg" instructions can be translated to
19808
;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19809
;; byte opcode instead of two, have a short form for byte operands),
19810
;; so do it for other CPUs as well.  Given that the value was dead,
19811
;; this should not create any new dependencies.  Pass on the sub-word
19812
;; versions if we're concerned about partial register stalls.
19813
 
19814
(define_peephole2
19815
  [(set (match_operand 0 "flags_reg_operand" "")
19816
        (match_operator 1 "compare_operator"
19817
          [(and:SI (match_operand:SI 2 "register_operand" "")
19818
                   (match_operand:SI 3 "immediate_operand" ""))
19819
           (const_int 0)]))]
19820
  "ix86_match_ccmode (insn, CCNOmode)
19821
   && (true_regnum (operands[2]) != 0
19822
       || satisfies_constraint_K (operands[3]))
19823
   && peep2_reg_dead_p (1, operands[2])"
19824
  [(parallel
19825
     [(set (match_dup 0)
19826
           (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19827
                            (const_int 0)]))
19828
      (set (match_dup 2)
19829
           (and:SI (match_dup 2) (match_dup 3)))])]
19830
  "")
19831
 
19832
;; We don't need to handle HImode case, because it will be promoted to SImode
19833
;; on ! TARGET_PARTIAL_REG_STALL
19834
 
19835
(define_peephole2
19836
  [(set (match_operand 0 "flags_reg_operand" "")
19837
        (match_operator 1 "compare_operator"
19838
          [(and:QI (match_operand:QI 2 "register_operand" "")
19839
                   (match_operand:QI 3 "immediate_operand" ""))
19840
           (const_int 0)]))]
19841
  "! TARGET_PARTIAL_REG_STALL
19842
   && ix86_match_ccmode (insn, CCNOmode)
19843
   && true_regnum (operands[2]) != 0
19844
   && peep2_reg_dead_p (1, operands[2])"
19845
  [(parallel
19846
     [(set (match_dup 0)
19847
           (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19848
                            (const_int 0)]))
19849
      (set (match_dup 2)
19850
           (and:QI (match_dup 2) (match_dup 3)))])]
19851
  "")
19852
 
19853
(define_peephole2
19854
  [(set (match_operand 0 "flags_reg_operand" "")
19855
        (match_operator 1 "compare_operator"
19856
          [(and:SI
19857
             (zero_extract:SI
19858
               (match_operand 2 "ext_register_operand" "")
19859
               (const_int 8)
19860
               (const_int 8))
19861
             (match_operand 3 "const_int_operand" ""))
19862
           (const_int 0)]))]
19863
  "! TARGET_PARTIAL_REG_STALL
19864
   && ix86_match_ccmode (insn, CCNOmode)
19865
   && true_regnum (operands[2]) != 0
19866
   && peep2_reg_dead_p (1, operands[2])"
19867
  [(parallel [(set (match_dup 0)
19868
                   (match_op_dup 1
19869
                     [(and:SI
19870
                        (zero_extract:SI
19871
                          (match_dup 2)
19872
                          (const_int 8)
19873
                          (const_int 8))
19874
                        (match_dup 3))
19875
                      (const_int 0)]))
19876
              (set (zero_extract:SI (match_dup 2)
19877
                                    (const_int 8)
19878
                                    (const_int 8))
19879
                   (and:SI
19880
                     (zero_extract:SI
19881
                       (match_dup 2)
19882
                       (const_int 8)
19883
                       (const_int 8))
19884
                     (match_dup 3)))])]
19885
  "")
19886
 
19887
;; Don't do logical operations with memory inputs.
19888
(define_peephole2
19889
  [(match_scratch:SI 2 "r")
19890
   (parallel [(set (match_operand:SI 0 "register_operand" "")
19891
                   (match_operator:SI 3 "arith_or_logical_operator"
19892
                     [(match_dup 0)
19893
                      (match_operand:SI 1 "memory_operand" "")]))
19894
              (clobber (reg:CC FLAGS_REG))])]
19895
  "! optimize_size && ! TARGET_READ_MODIFY"
19896
  [(set (match_dup 2) (match_dup 1))
19897
   (parallel [(set (match_dup 0)
19898
                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19899
              (clobber (reg:CC FLAGS_REG))])]
19900
  "")
19901
 
19902
(define_peephole2
19903
  [(match_scratch:SI 2 "r")
19904
   (parallel [(set (match_operand:SI 0 "register_operand" "")
19905
                   (match_operator:SI 3 "arith_or_logical_operator"
19906
                     [(match_operand:SI 1 "memory_operand" "")
19907
                      (match_dup 0)]))
19908
              (clobber (reg:CC FLAGS_REG))])]
19909
  "! optimize_size && ! TARGET_READ_MODIFY"
19910
  [(set (match_dup 2) (match_dup 1))
19911
   (parallel [(set (match_dup 0)
19912
                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19913
              (clobber (reg:CC FLAGS_REG))])]
19914
  "")
19915
 
19916
; Don't do logical operations with memory outputs
19917
;
19918
; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19919
; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19920
; the same decoder scheduling characteristics as the original.
19921
 
19922
(define_peephole2
19923
  [(match_scratch:SI 2 "r")
19924
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19925
                   (match_operator:SI 3 "arith_or_logical_operator"
19926
                     [(match_dup 0)
19927
                      (match_operand:SI 1 "nonmemory_operand" "")]))
19928
              (clobber (reg:CC FLAGS_REG))])]
19929
  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19930
  [(set (match_dup 2) (match_dup 0))
19931
   (parallel [(set (match_dup 2)
19932
                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19933
              (clobber (reg:CC FLAGS_REG))])
19934
   (set (match_dup 0) (match_dup 2))]
19935
  "")
19936
 
19937
(define_peephole2
19938
  [(match_scratch:SI 2 "r")
19939
   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19940
                   (match_operator:SI 3 "arith_or_logical_operator"
19941
                     [(match_operand:SI 1 "nonmemory_operand" "")
19942
                      (match_dup 0)]))
19943
              (clobber (reg:CC FLAGS_REG))])]
19944
  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19945
  [(set (match_dup 2) (match_dup 0))
19946
   (parallel [(set (match_dup 2)
19947
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19948
              (clobber (reg:CC FLAGS_REG))])
19949
   (set (match_dup 0) (match_dup 2))]
19950
  "")
19951
 
19952
;; Attempt to always use XOR for zeroing registers.
19953
(define_peephole2
19954
  [(set (match_operand 0 "register_operand" "")
19955
        (match_operand 1 "const0_operand" ""))]
19956
  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19957
   && (! TARGET_USE_MOV0 || optimize_size)
19958
   && GENERAL_REG_P (operands[0])
19959
   && peep2_regno_dead_p (0, FLAGS_REG)"
19960
  [(parallel [(set (match_dup 0) (const_int 0))
19961
              (clobber (reg:CC FLAGS_REG))])]
19962
{
19963
  operands[0] = gen_lowpart (word_mode, operands[0]);
19964
})
19965
 
19966
(define_peephole2
19967
  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19968
        (const_int 0))]
19969
  "(GET_MODE (operands[0]) == QImode
19970
    || GET_MODE (operands[0]) == HImode)
19971
   && (! TARGET_USE_MOV0 || optimize_size)
19972
   && peep2_regno_dead_p (0, FLAGS_REG)"
19973
  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19974
              (clobber (reg:CC FLAGS_REG))])])
19975
 
19976
;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19977
(define_peephole2
19978
  [(set (match_operand 0 "register_operand" "")
19979
        (const_int -1))]
19980
  "(GET_MODE (operands[0]) == HImode
19981
    || GET_MODE (operands[0]) == SImode
19982
    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19983
   && (optimize_size || TARGET_PENTIUM)
19984
   && peep2_regno_dead_p (0, FLAGS_REG)"
19985
  [(parallel [(set (match_dup 0) (const_int -1))
19986
              (clobber (reg:CC FLAGS_REG))])]
19987
  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19988
                              operands[0]);")
19989
 
19990
;; Attempt to convert simple leas to adds. These can be created by
19991
;; move expanders.
19992
(define_peephole2
19993
  [(set (match_operand:SI 0 "register_operand" "")
19994
        (plus:SI (match_dup 0)
19995
                 (match_operand:SI 1 "nonmemory_operand" "")))]
19996
  "peep2_regno_dead_p (0, FLAGS_REG)"
19997
  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19998
              (clobber (reg:CC FLAGS_REG))])]
19999
  "")
20000
 
20001
(define_peephole2
20002
  [(set (match_operand:SI 0 "register_operand" "")
20003
        (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20004
                            (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20005
  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20006
  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20007
              (clobber (reg:CC FLAGS_REG))])]
20008
  "operands[2] = gen_lowpart (SImode, operands[2]);")
20009
 
20010
(define_peephole2
20011
  [(set (match_operand:DI 0 "register_operand" "")
20012
        (plus:DI (match_dup 0)
20013
                 (match_operand:DI 1 "x86_64_general_operand" "")))]
20014
  "peep2_regno_dead_p (0, FLAGS_REG)"
20015
  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20016
              (clobber (reg:CC FLAGS_REG))])]
20017
  "")
20018
 
20019
(define_peephole2
20020
  [(set (match_operand:SI 0 "register_operand" "")
20021
        (mult:SI (match_dup 0)
20022
                 (match_operand:SI 1 "const_int_operand" "")))]
20023
  "exact_log2 (INTVAL (operands[1])) >= 0
20024
   && peep2_regno_dead_p (0, FLAGS_REG)"
20025
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20026
              (clobber (reg:CC FLAGS_REG))])]
20027
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20028
 
20029
(define_peephole2
20030
  [(set (match_operand:DI 0 "register_operand" "")
20031
        (mult:DI (match_dup 0)
20032
                 (match_operand:DI 1 "const_int_operand" "")))]
20033
  "exact_log2 (INTVAL (operands[1])) >= 0
20034
   && peep2_regno_dead_p (0, FLAGS_REG)"
20035
  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20036
              (clobber (reg:CC FLAGS_REG))])]
20037
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20038
 
20039
(define_peephole2
20040
  [(set (match_operand:SI 0 "register_operand" "")
20041
        (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20042
                   (match_operand:DI 2 "const_int_operand" "")) 0))]
20043
  "exact_log2 (INTVAL (operands[2])) >= 0
20044
   && REGNO (operands[0]) == REGNO (operands[1])
20045
   && peep2_regno_dead_p (0, FLAGS_REG)"
20046
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20047
              (clobber (reg:CC FLAGS_REG))])]
20048
  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20049
 
20050
;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20051
;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20052
;; many CPUs it is also faster, since special hardware to avoid esp
20053
;; dependencies is present.
20054
 
20055
;; While some of these conversions may be done using splitters, we use peepholes
20056
;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20057
 
20058
;; Convert prologue esp subtractions to push.
20059
;; We need register to push.  In order to keep verify_flow_info happy we have
20060
;; two choices
20061
;; - use scratch and clobber it in order to avoid dependencies
20062
;; - use already live register
20063
;; We can't use the second way right now, since there is no reliable way how to
20064
;; verify that given register is live.  First choice will also most likely in
20065
;; fewer dependencies.  On the place of esp adjustments it is very likely that
20066
;; call clobbered registers are dead.  We may want to use base pointer as an
20067
;; alternative when no register is available later.
20068
 
20069
(define_peephole2
20070
  [(match_scratch:SI 0 "r")
20071
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20072
              (clobber (reg:CC FLAGS_REG))
20073
              (clobber (mem:BLK (scratch)))])]
20074
  "optimize_size || !TARGET_SUB_ESP_4"
20075
  [(clobber (match_dup 0))
20076
   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20077
              (clobber (mem:BLK (scratch)))])])
20078
 
20079
(define_peephole2
20080
  [(match_scratch:SI 0 "r")
20081
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20082
              (clobber (reg:CC FLAGS_REG))
20083
              (clobber (mem:BLK (scratch)))])]
20084
  "optimize_size || !TARGET_SUB_ESP_8"
20085
  [(clobber (match_dup 0))
20086
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20087
   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20088
              (clobber (mem:BLK (scratch)))])])
20089
 
20090
;; Convert esp subtractions to push.
20091
(define_peephole2
20092
  [(match_scratch:SI 0 "r")
20093
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20094
              (clobber (reg:CC FLAGS_REG))])]
20095
  "optimize_size || !TARGET_SUB_ESP_4"
20096
  [(clobber (match_dup 0))
20097
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20098
 
20099
(define_peephole2
20100
  [(match_scratch:SI 0 "r")
20101
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20102
              (clobber (reg:CC FLAGS_REG))])]
20103
  "optimize_size || !TARGET_SUB_ESP_8"
20104
  [(clobber (match_dup 0))
20105
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20106
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20107
 
20108
;; Convert epilogue deallocator to pop.
20109
(define_peephole2
20110
  [(match_scratch:SI 0 "r")
20111
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20112
              (clobber (reg:CC FLAGS_REG))
20113
              (clobber (mem:BLK (scratch)))])]
20114
  "optimize_size || !TARGET_ADD_ESP_4"
20115
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20116
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20117
              (clobber (mem:BLK (scratch)))])]
20118
  "")
20119
 
20120
;; Two pops case is tricky, since pop causes dependency on destination register.
20121
;; We use two registers if available.
20122
(define_peephole2
20123
  [(match_scratch:SI 0 "r")
20124
   (match_scratch:SI 1 "r")
20125
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20126
              (clobber (reg:CC FLAGS_REG))
20127
              (clobber (mem:BLK (scratch)))])]
20128
  "optimize_size || !TARGET_ADD_ESP_8"
20129
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20130
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20131
              (clobber (mem:BLK (scratch)))])
20132
   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20133
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20134
  "")
20135
 
20136
(define_peephole2
20137
  [(match_scratch:SI 0 "r")
20138
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20139
              (clobber (reg:CC FLAGS_REG))
20140
              (clobber (mem:BLK (scratch)))])]
20141
  "optimize_size"
20142
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20143
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20144
              (clobber (mem:BLK (scratch)))])
20145
   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20146
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20147
  "")
20148
 
20149
;; Convert esp additions to pop.
20150
(define_peephole2
20151
  [(match_scratch:SI 0 "r")
20152
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20153
              (clobber (reg:CC FLAGS_REG))])]
20154
  ""
20155
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20156
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20157
  "")
20158
 
20159
;; Two pops case is tricky, since pop causes dependency on destination register.
20160
;; We use two registers if available.
20161
(define_peephole2
20162
  [(match_scratch:SI 0 "r")
20163
   (match_scratch:SI 1 "r")
20164
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20165
              (clobber (reg:CC FLAGS_REG))])]
20166
  ""
20167
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20168
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20169
   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20170
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20171
  "")
20172
 
20173
(define_peephole2
20174
  [(match_scratch:SI 0 "r")
20175
   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20176
              (clobber (reg:CC FLAGS_REG))])]
20177
  "optimize_size"
20178
  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20179
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20180
   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20181
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20182
  "")
20183
 
20184
;; Convert compares with 1 to shorter inc/dec operations when CF is not
20185
;; required and register dies.  Similarly for 128 to plus -128.
20186
(define_peephole2
20187
  [(set (match_operand 0 "flags_reg_operand" "")
20188
        (match_operator 1 "compare_operator"
20189
          [(match_operand 2 "register_operand" "")
20190
           (match_operand 3 "const_int_operand" "")]))]
20191
  "(INTVAL (operands[3]) == -1
20192
    || INTVAL (operands[3]) == 1
20193
    || INTVAL (operands[3]) == 128)
20194
   && ix86_match_ccmode (insn, CCGCmode)
20195
   && peep2_reg_dead_p (1, operands[2])"
20196
  [(parallel [(set (match_dup 0)
20197
                   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20198
              (clobber (match_dup 2))])]
20199
  "")
20200
 
20201
(define_peephole2
20202
  [(match_scratch:DI 0 "r")
20203
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20204
              (clobber (reg:CC FLAGS_REG))
20205
              (clobber (mem:BLK (scratch)))])]
20206
  "optimize_size || !TARGET_SUB_ESP_4"
20207
  [(clobber (match_dup 0))
20208
   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20209
              (clobber (mem:BLK (scratch)))])])
20210
 
20211
(define_peephole2
20212
  [(match_scratch:DI 0 "r")
20213
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20214
              (clobber (reg:CC FLAGS_REG))
20215
              (clobber (mem:BLK (scratch)))])]
20216
  "optimize_size || !TARGET_SUB_ESP_8"
20217
  [(clobber (match_dup 0))
20218
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20219
   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20220
              (clobber (mem:BLK (scratch)))])])
20221
 
20222
;; Convert esp subtractions to push.
20223
(define_peephole2
20224
  [(match_scratch:DI 0 "r")
20225
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20226
              (clobber (reg:CC FLAGS_REG))])]
20227
  "optimize_size || !TARGET_SUB_ESP_4"
20228
  [(clobber (match_dup 0))
20229
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20230
 
20231
(define_peephole2
20232
  [(match_scratch:DI 0 "r")
20233
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20234
              (clobber (reg:CC FLAGS_REG))])]
20235
  "optimize_size || !TARGET_SUB_ESP_8"
20236
  [(clobber (match_dup 0))
20237
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20238
   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20239
 
20240
;; Convert epilogue deallocator to pop.
20241
(define_peephole2
20242
  [(match_scratch:DI 0 "r")
20243
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20244
              (clobber (reg:CC FLAGS_REG))
20245
              (clobber (mem:BLK (scratch)))])]
20246
  "optimize_size || !TARGET_ADD_ESP_4"
20247
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20248
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20249
              (clobber (mem:BLK (scratch)))])]
20250
  "")
20251
 
20252
;; Two pops case is tricky, since pop causes dependency on destination register.
20253
;; We use two registers if available.
20254
(define_peephole2
20255
  [(match_scratch:DI 0 "r")
20256
   (match_scratch:DI 1 "r")
20257
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20258
              (clobber (reg:CC FLAGS_REG))
20259
              (clobber (mem:BLK (scratch)))])]
20260
  "optimize_size || !TARGET_ADD_ESP_8"
20261
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20262
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20263
              (clobber (mem:BLK (scratch)))])
20264
   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20265
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20266
  "")
20267
 
20268
(define_peephole2
20269
  [(match_scratch:DI 0 "r")
20270
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20271
              (clobber (reg:CC FLAGS_REG))
20272
              (clobber (mem:BLK (scratch)))])]
20273
  "optimize_size"
20274
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20275
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20276
              (clobber (mem:BLK (scratch)))])
20277
   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20278
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20279
  "")
20280
 
20281
;; Convert esp additions to pop.
20282
(define_peephole2
20283
  [(match_scratch:DI 0 "r")
20284
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20285
              (clobber (reg:CC FLAGS_REG))])]
20286
  ""
20287
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20288
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20289
  "")
20290
 
20291
;; Two pops case is tricky, since pop causes dependency on destination register.
20292
;; We use two registers if available.
20293
(define_peephole2
20294
  [(match_scratch:DI 0 "r")
20295
   (match_scratch:DI 1 "r")
20296
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20297
              (clobber (reg:CC FLAGS_REG))])]
20298
  ""
20299
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20300
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20301
   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20302
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20303
  "")
20304
 
20305
(define_peephole2
20306
  [(match_scratch:DI 0 "r")
20307
   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20308
              (clobber (reg:CC FLAGS_REG))])]
20309
  "optimize_size"
20310
  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20311
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20312
   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20313
              (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20314
  "")
20315
 
20316
;; Convert imul by three, five and nine into lea
20317
(define_peephole2
20318
  [(parallel
20319
    [(set (match_operand:SI 0 "register_operand" "")
20320
          (mult:SI (match_operand:SI 1 "register_operand" "")
20321
                   (match_operand:SI 2 "const_int_operand" "")))
20322
     (clobber (reg:CC FLAGS_REG))])]
20323
  "INTVAL (operands[2]) == 3
20324
   || INTVAL (operands[2]) == 5
20325
   || INTVAL (operands[2]) == 9"
20326
  [(set (match_dup 0)
20327
        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20328
                 (match_dup 1)))]
20329
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20330
 
20331
(define_peephole2
20332
  [(parallel
20333
    [(set (match_operand:SI 0 "register_operand" "")
20334
          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20335
                   (match_operand:SI 2 "const_int_operand" "")))
20336
     (clobber (reg:CC FLAGS_REG))])]
20337
  "!optimize_size
20338
   && (INTVAL (operands[2]) == 3
20339
       || INTVAL (operands[2]) == 5
20340
       || INTVAL (operands[2]) == 9)"
20341
  [(set (match_dup 0) (match_dup 1))
20342
   (set (match_dup 0)
20343
        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20344
                 (match_dup 0)))]
20345
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20346
 
20347
(define_peephole2
20348
  [(parallel
20349
    [(set (match_operand:DI 0 "register_operand" "")
20350
          (mult:DI (match_operand:DI 1 "register_operand" "")
20351
                   (match_operand:DI 2 "const_int_operand" "")))
20352
     (clobber (reg:CC FLAGS_REG))])]
20353
  "TARGET_64BIT
20354
   && (INTVAL (operands[2]) == 3
20355
       || INTVAL (operands[2]) == 5
20356
       || INTVAL (operands[2]) == 9)"
20357
  [(set (match_dup 0)
20358
        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20359
                 (match_dup 1)))]
20360
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20361
 
20362
(define_peephole2
20363
  [(parallel
20364
    [(set (match_operand:DI 0 "register_operand" "")
20365
          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20366
                   (match_operand:DI 2 "const_int_operand" "")))
20367
     (clobber (reg:CC FLAGS_REG))])]
20368
  "TARGET_64BIT
20369
   && !optimize_size
20370
   && (INTVAL (operands[2]) == 3
20371
       || INTVAL (operands[2]) == 5
20372
       || INTVAL (operands[2]) == 9)"
20373
  [(set (match_dup 0) (match_dup 1))
20374
   (set (match_dup 0)
20375
        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20376
                 (match_dup 0)))]
20377
  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20378
 
20379
;; Imul $32bit_imm, mem, reg is vector decoded, while
20380
;; imul $32bit_imm, reg, reg is direct decoded.
20381
(define_peephole2
20382
  [(match_scratch:DI 3 "r")
20383
   (parallel [(set (match_operand:DI 0 "register_operand" "")
20384
                   (mult:DI (match_operand:DI 1 "memory_operand" "")
20385
                            (match_operand:DI 2 "immediate_operand" "")))
20386
              (clobber (reg:CC FLAGS_REG))])]
20387
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20388
   && !satisfies_constraint_K (operands[2])"
20389
  [(set (match_dup 3) (match_dup 1))
20390
   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20391
              (clobber (reg:CC FLAGS_REG))])]
20392
"")
20393
 
20394
(define_peephole2
20395
  [(match_scratch:SI 3 "r")
20396
   (parallel [(set (match_operand:SI 0 "register_operand" "")
20397
                   (mult:SI (match_operand:SI 1 "memory_operand" "")
20398
                            (match_operand:SI 2 "immediate_operand" "")))
20399
              (clobber (reg:CC FLAGS_REG))])]
20400
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20401
   && !satisfies_constraint_K (operands[2])"
20402
  [(set (match_dup 3) (match_dup 1))
20403
   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20404
              (clobber (reg:CC FLAGS_REG))])]
20405
"")
20406
 
20407
(define_peephole2
20408
  [(match_scratch:SI 3 "r")
20409
   (parallel [(set (match_operand:DI 0 "register_operand" "")
20410
                   (zero_extend:DI
20411
                     (mult:SI (match_operand:SI 1 "memory_operand" "")
20412
                              (match_operand:SI 2 "immediate_operand" ""))))
20413
              (clobber (reg:CC FLAGS_REG))])]
20414
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20415
   && !satisfies_constraint_K (operands[2])"
20416
  [(set (match_dup 3) (match_dup 1))
20417
   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20418
              (clobber (reg:CC FLAGS_REG))])]
20419
"")
20420
 
20421
;; imul $8/16bit_imm, regmem, reg is vector decoded.
20422
;; Convert it into imul reg, reg
20423
;; It would be better to force assembler to encode instruction using long
20424
;; immediate, but there is apparently no way to do so.
20425
(define_peephole2
20426
  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20427
                   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20428
                            (match_operand:DI 2 "const_int_operand" "")))
20429
              (clobber (reg:CC FLAGS_REG))])
20430
   (match_scratch:DI 3 "r")]
20431
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20432
   && satisfies_constraint_K (operands[2])"
20433
  [(set (match_dup 3) (match_dup 2))
20434
   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20435
              (clobber (reg:CC FLAGS_REG))])]
20436
{
20437
  if (!rtx_equal_p (operands[0], operands[1]))
20438
    emit_move_insn (operands[0], operands[1]);
20439
})
20440
 
20441
(define_peephole2
20442
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20443
                   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20444
                            (match_operand:SI 2 "const_int_operand" "")))
20445
              (clobber (reg:CC FLAGS_REG))])
20446
   (match_scratch:SI 3 "r")]
20447
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20448
   && satisfies_constraint_K (operands[2])"
20449
  [(set (match_dup 3) (match_dup 2))
20450
   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20451
              (clobber (reg:CC FLAGS_REG))])]
20452
{
20453
  if (!rtx_equal_p (operands[0], operands[1]))
20454
    emit_move_insn (operands[0], operands[1]);
20455
})
20456
 
20457
(define_peephole2
20458
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20459
                   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20460
                            (match_operand:HI 2 "immediate_operand" "")))
20461
              (clobber (reg:CC FLAGS_REG))])
20462
   (match_scratch:HI 3 "r")]
20463
  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20464
  [(set (match_dup 3) (match_dup 2))
20465
   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20466
              (clobber (reg:CC FLAGS_REG))])]
20467
{
20468
  if (!rtx_equal_p (operands[0], operands[1]))
20469
    emit_move_insn (operands[0], operands[1]);
20470
})
20471
 
20472
;; After splitting up read-modify operations, array accesses with memory
20473
;; operands might end up in form:
20474
;;  sall    $2, %eax
20475
;;  movl    4(%esp), %edx
20476
;;  addl    %edx, %eax
20477
;; instead of pre-splitting:
20478
;;  sall    $2, %eax
20479
;;  addl    4(%esp), %eax
20480
;; Turn it into:
20481
;;  movl    4(%esp), %edx
20482
;;  leal    (%edx,%eax,4), %eax
20483
 
20484
(define_peephole2
20485
  [(parallel [(set (match_operand 0 "register_operand" "")
20486
                   (ashift (match_operand 1 "register_operand" "")
20487
                           (match_operand 2 "const_int_operand" "")))
20488
               (clobber (reg:CC FLAGS_REG))])
20489
   (set (match_operand 3 "register_operand")
20490
        (match_operand 4 "x86_64_general_operand" ""))
20491
   (parallel [(set (match_operand 5 "register_operand" "")
20492
                   (plus (match_operand 6 "register_operand" "")
20493
                         (match_operand 7 "register_operand" "")))
20494
                   (clobber (reg:CC FLAGS_REG))])]
20495
  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20496
   /* Validate MODE for lea.  */
20497
   && ((!TARGET_PARTIAL_REG_STALL
20498
        && (GET_MODE (operands[0]) == QImode
20499
            || GET_MODE (operands[0]) == HImode))
20500
       || GET_MODE (operands[0]) == SImode
20501
       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20502
   /* We reorder load and the shift.  */
20503
   && !rtx_equal_p (operands[1], operands[3])
20504
   && !reg_overlap_mentioned_p (operands[0], operands[4])
20505
   /* Last PLUS must consist of operand 0 and 3.  */
20506
   && !rtx_equal_p (operands[0], operands[3])
20507
   && (rtx_equal_p (operands[3], operands[6])
20508
       || rtx_equal_p (operands[3], operands[7]))
20509
   && (rtx_equal_p (operands[0], operands[6])
20510
       || rtx_equal_p (operands[0], operands[7]))
20511
   /* The intermediate operand 0 must die or be same as output.  */
20512
   && (rtx_equal_p (operands[0], operands[5])
20513
       || peep2_reg_dead_p (3, operands[0]))"
20514
  [(set (match_dup 3) (match_dup 4))
20515
   (set (match_dup 0) (match_dup 1))]
20516
{
20517
  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20518
  int scale = 1 << INTVAL (operands[2]);
20519
  rtx index = gen_lowpart (Pmode, operands[1]);
20520
  rtx base = gen_lowpart (Pmode, operands[3]);
20521
  rtx dest = gen_lowpart (mode, operands[5]);
20522
 
20523
  operands[1] = gen_rtx_PLUS (Pmode, base,
20524
                              gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20525
  if (mode != Pmode)
20526
    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20527
  operands[0] = dest;
20528
})
20529
 
20530
;; Call-value patterns last so that the wildcard operand does not
20531
;; disrupt insn-recog's switch tables.
20532
 
20533
(define_insn "*call_value_pop_0"
20534
  [(set (match_operand 0 "" "")
20535
        (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20536
              (match_operand:SI 2 "" "")))
20537
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20538
                            (match_operand:SI 3 "immediate_operand" "")))]
20539
  "!TARGET_64BIT"
20540
{
20541
  if (SIBLING_CALL_P (insn))
20542
    return "jmp\t%P1";
20543
  else
20544
    return "call\t%P1";
20545
}
20546
  [(set_attr "type" "callv")])
20547
 
20548
(define_insn "*call_value_pop_1"
20549
  [(set (match_operand 0 "" "")
20550
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20551
              (match_operand:SI 2 "" "")))
20552
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20553
                            (match_operand:SI 3 "immediate_operand" "i")))]
20554
  "!TARGET_64BIT"
20555
{
20556
  if (constant_call_address_operand (operands[1], Pmode))
20557
    {
20558
      if (SIBLING_CALL_P (insn))
20559
        return "jmp\t%P1";
20560
      else
20561
        return "call\t%P1";
20562
    }
20563
  if (SIBLING_CALL_P (insn))
20564
    return "jmp\t%A1";
20565
  else
20566
    return "call\t%A1";
20567
}
20568
  [(set_attr "type" "callv")])
20569
 
20570
(define_insn "*call_value_0"
20571
  [(set (match_operand 0 "" "")
20572
        (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20573
              (match_operand:SI 2 "" "")))]
20574
  "!TARGET_64BIT"
20575
{
20576
  if (SIBLING_CALL_P (insn))
20577
    return "jmp\t%P1";
20578
  else
20579
    return "call\t%P1";
20580
}
20581
  [(set_attr "type" "callv")])
20582
 
20583
(define_insn "*call_value_0_rex64"
20584
  [(set (match_operand 0 "" "")
20585
        (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20586
              (match_operand:DI 2 "const_int_operand" "")))]
20587
  "TARGET_64BIT"
20588
{
20589
  if (SIBLING_CALL_P (insn))
20590
    return "jmp\t%P1";
20591
  else
20592
    return "call\t%P1";
20593
}
20594
  [(set_attr "type" "callv")])
20595
 
20596
(define_insn "*call_value_1"
20597
  [(set (match_operand 0 "" "")
20598
        (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20599
              (match_operand:SI 2 "" "")))]
20600
  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20601
{
20602
  if (constant_call_address_operand (operands[1], Pmode))
20603
    return "call\t%P1";
20604
  return "call\t%A1";
20605
}
20606
  [(set_attr "type" "callv")])
20607
 
20608
(define_insn "*sibcall_value_1"
20609
  [(set (match_operand 0 "" "")
20610
        (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20611
              (match_operand:SI 2 "" "")))]
20612
  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20613
{
20614
  if (constant_call_address_operand (operands[1], Pmode))
20615
    return "jmp\t%P1";
20616
  return "jmp\t%A1";
20617
}
20618
  [(set_attr "type" "callv")])
20619
 
20620
(define_insn "*call_value_1_rex64"
20621
  [(set (match_operand 0 "" "")
20622
        (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20623
              (match_operand:DI 2 "" "")))]
20624
  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20625
{
20626
  if (constant_call_address_operand (operands[1], Pmode))
20627
    return "call\t%P1";
20628
  return "call\t%A1";
20629
}
20630
  [(set_attr "type" "callv")])
20631
 
20632
(define_insn "*sibcall_value_1_rex64"
20633
  [(set (match_operand 0 "" "")
20634
        (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20635
              (match_operand:DI 2 "" "")))]
20636
  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20637
  "jmp\t%P1"
20638
  [(set_attr "type" "callv")])
20639
 
20640
(define_insn "*sibcall_value_1_rex64_v"
20641
  [(set (match_operand 0 "" "")
20642
        (call (mem:QI (reg:DI 40))
20643
              (match_operand:DI 1 "" "")))]
20644
  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20645
  "jmp\t*%%r11"
20646
  [(set_attr "type" "callv")])
20647
 
20648
;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20649
;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20650
;; caught for use by garbage collectors and the like.  Using an insn that
20651
;; maps to SIGILL makes it more likely the program will rightfully die.
20652
;; Keeping with tradition, "6" is in honor of #UD.
20653
(define_insn "trap"
20654
  [(trap_if (const_int 1) (const_int 6))]
20655
  ""
20656
  { return ASM_SHORT "0x0b0f"; }
20657
  [(set_attr "length" "2")])
20658
 
20659
(define_expand "sse_prologue_save"
20660
  [(parallel [(set (match_operand:BLK 0 "" "")
20661
                   (unspec:BLK [(reg:DI 21)
20662
                                (reg:DI 22)
20663
                                (reg:DI 23)
20664
                                (reg:DI 24)
20665
                                (reg:DI 25)
20666
                                (reg:DI 26)
20667
                                (reg:DI 27)
20668
                                (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20669
              (use (match_operand:DI 1 "register_operand" ""))
20670
              (use (match_operand:DI 2 "immediate_operand" ""))
20671
              (use (label_ref:DI (match_operand 3 "" "")))])]
20672
  "TARGET_64BIT"
20673
  "")
20674
 
20675
(define_insn "*sse_prologue_save_insn"
20676
  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20677
                          (match_operand:DI 4 "const_int_operand" "n")))
20678
        (unspec:BLK [(reg:DI 21)
20679
                     (reg:DI 22)
20680
                     (reg:DI 23)
20681
                     (reg:DI 24)
20682
                     (reg:DI 25)
20683
                     (reg:DI 26)
20684
                     (reg:DI 27)
20685
                     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20686
   (use (match_operand:DI 1 "register_operand" "r"))
20687
   (use (match_operand:DI 2 "const_int_operand" "i"))
20688
   (use (label_ref:DI (match_operand 3 "" "X")))]
20689
  "TARGET_64BIT
20690
   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20691
   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20692
  "*
20693
{
20694
  int i;
20695
  operands[0] = gen_rtx_MEM (Pmode,
20696
                             gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20697
  output_asm_insn (\"jmp\\t%A1\", operands);
20698
  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20699
    {
20700
      operands[4] = adjust_address (operands[0], DImode, i*16);
20701
      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20702
      PUT_MODE (operands[4], TImode);
20703
      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20704
        output_asm_insn (\"rex\", operands);
20705
      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20706
    }
20707
  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20708
                             CODE_LABEL_NUMBER (operands[3]));
20709
  RET;
20710
}
20711
  "
20712
  [(set_attr "type" "other")
20713
   (set_attr "length_immediate" "0")
20714
   (set_attr "length_address" "0")
20715
   (set_attr "length" "135")
20716
   (set_attr "memory" "store")
20717
   (set_attr "modrm" "0")
20718
   (set_attr "mode" "DI")])
20719
 
20720
(define_expand "prefetch"
20721
  [(prefetch (match_operand 0 "address_operand" "")
20722
             (match_operand:SI 1 "const_int_operand" "")
20723
             (match_operand:SI 2 "const_int_operand" ""))]
20724
  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20725
{
20726
  int rw = INTVAL (operands[1]);
20727
  int locality = INTVAL (operands[2]);
20728
 
20729
  gcc_assert (rw == 0 || rw == 1);
20730
  gcc_assert (locality >= 0 && locality <= 3);
20731
  gcc_assert (GET_MODE (operands[0]) == Pmode
20732
              || GET_MODE (operands[0]) == VOIDmode);
20733
 
20734
  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20735
     supported by SSE counterpart or the SSE prefetch is not available
20736
     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20737
     of locality.  */
20738
  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20739
    operands[2] = GEN_INT (3);
20740
  else
20741
    operands[1] = const0_rtx;
20742
})
20743
 
20744
(define_insn "*prefetch_sse"
20745
  [(prefetch (match_operand:SI 0 "address_operand" "p")
20746
             (const_int 0)
20747
             (match_operand:SI 1 "const_int_operand" ""))]
20748
  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20749
{
20750
  static const char * const patterns[4] = {
20751
   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20752
  };
20753
 
20754
  int locality = INTVAL (operands[1]);
20755
  gcc_assert (locality >= 0 && locality <= 3);
20756
 
20757
  return patterns[locality];
20758
}
20759
  [(set_attr "type" "sse")
20760
   (set_attr "memory" "none")])
20761
 
20762
(define_insn "*prefetch_sse_rex"
20763
  [(prefetch (match_operand:DI 0 "address_operand" "p")
20764
             (const_int 0)
20765
             (match_operand:SI 1 "const_int_operand" ""))]
20766
  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20767
{
20768
  static const char * const patterns[4] = {
20769
   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20770
  };
20771
 
20772
  int locality = INTVAL (operands[1]);
20773
  gcc_assert (locality >= 0 && locality <= 3);
20774
 
20775
  return patterns[locality];
20776
}
20777
  [(set_attr "type" "sse")
20778
   (set_attr "memory" "none")])
20779
 
20780
(define_insn "*prefetch_3dnow"
20781
  [(prefetch (match_operand:SI 0 "address_operand" "p")
20782
             (match_operand:SI 1 "const_int_operand" "n")
20783
             (const_int 3))]
20784
  "TARGET_3DNOW && !TARGET_64BIT"
20785
{
20786
  if (INTVAL (operands[1]) == 0)
20787
    return "prefetch\t%a0";
20788
  else
20789
    return "prefetchw\t%a0";
20790
}
20791
  [(set_attr "type" "mmx")
20792
   (set_attr "memory" "none")])
20793
 
20794
(define_insn "*prefetch_3dnow_rex"
20795
  [(prefetch (match_operand:DI 0 "address_operand" "p")
20796
             (match_operand:SI 1 "const_int_operand" "n")
20797
             (const_int 3))]
20798
  "TARGET_3DNOW && TARGET_64BIT"
20799
{
20800
  if (INTVAL (operands[1]) == 0)
20801
    return "prefetch\t%a0";
20802
  else
20803
    return "prefetchw\t%a0";
20804
}
20805
  [(set_attr "type" "mmx")
20806
   (set_attr "memory" "none")])
20807
 
20808
(define_expand "stack_protect_set"
20809
  [(match_operand 0 "memory_operand" "")
20810
   (match_operand 1 "memory_operand" "")]
20811
  ""
20812
{
20813
#ifdef TARGET_THREAD_SSP_OFFSET
20814
  if (TARGET_64BIT)
20815
    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20816
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20817
  else
20818
    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20819
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20820
#else
20821
  if (TARGET_64BIT)
20822
    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20823
  else
20824
    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20825
#endif
20826
  DONE;
20827
})
20828
 
20829
(define_insn "stack_protect_set_si"
20830
  [(set (match_operand:SI 0 "memory_operand" "=m")
20831
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20832
   (set (match_scratch:SI 2 "=&r") (const_int 0))
20833
   (clobber (reg:CC FLAGS_REG))]
20834
  ""
20835
  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20836
  [(set_attr "type" "multi")])
20837
 
20838
(define_insn "stack_protect_set_di"
20839
  [(set (match_operand:DI 0 "memory_operand" "=m")
20840
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20841
   (set (match_scratch:DI 2 "=&r") (const_int 0))
20842
   (clobber (reg:CC FLAGS_REG))]
20843
  "TARGET_64BIT"
20844
  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20845
  [(set_attr "type" "multi")])
20846
 
20847
(define_insn "stack_tls_protect_set_si"
20848
  [(set (match_operand:SI 0 "memory_operand" "=m")
20849
        (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20850
   (set (match_scratch:SI 2 "=&r") (const_int 0))
20851
   (clobber (reg:CC FLAGS_REG))]
20852
  ""
20853
  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20854
  [(set_attr "type" "multi")])
20855
 
20856
(define_insn "stack_tls_protect_set_di"
20857
  [(set (match_operand:DI 0 "memory_operand" "=m")
20858
        (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20859
   (set (match_scratch:DI 2 "=&r") (const_int 0))
20860
   (clobber (reg:CC FLAGS_REG))]
20861
  "TARGET_64BIT"
20862
  {
20863
     /* The kernel uses a different segment register for performance reasons; a
20864
        system call would not have to trash the userspace segment register,
20865
        which would be expensive */
20866
     if (ix86_cmodel != CM_KERNEL)
20867
        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20868
     else
20869
        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20870
  }
20871
  [(set_attr "type" "multi")])
20872
 
20873
(define_expand "stack_protect_test"
20874
  [(match_operand 0 "memory_operand" "")
20875
   (match_operand 1 "memory_operand" "")
20876
   (match_operand 2 "" "")]
20877
  ""
20878
{
20879
  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20880
  ix86_compare_op0 = operands[0];
20881
  ix86_compare_op1 = operands[1];
20882
  ix86_compare_emitted = flags;
20883
 
20884
#ifdef TARGET_THREAD_SSP_OFFSET
20885
  if (TARGET_64BIT)
20886
    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20887
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20888
  else
20889
    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20890
                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20891
#else
20892
  if (TARGET_64BIT)
20893
    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20894
  else
20895
    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20896
#endif
20897
  emit_jump_insn (gen_beq (operands[2]));
20898
  DONE;
20899
})
20900
 
20901
(define_insn "stack_protect_test_si"
20902
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20903
        (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20904
                     (match_operand:SI 2 "memory_operand" "m")]
20905
                    UNSPEC_SP_TEST))
20906
   (clobber (match_scratch:SI 3 "=&r"))]
20907
  ""
20908
  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20909
  [(set_attr "type" "multi")])
20910
 
20911
(define_insn "stack_protect_test_di"
20912
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20913
        (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20914
                     (match_operand:DI 2 "memory_operand" "m")]
20915
                    UNSPEC_SP_TEST))
20916
   (clobber (match_scratch:DI 3 "=&r"))]
20917
  "TARGET_64BIT"
20918
  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20919
  [(set_attr "type" "multi")])
20920
 
20921
(define_insn "stack_tls_protect_test_si"
20922
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20923
        (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20924
                     (match_operand:SI 2 "const_int_operand" "i")]
20925
                    UNSPEC_SP_TLS_TEST))
20926
   (clobber (match_scratch:SI 3 "=r"))]
20927
  ""
20928
  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20929
  [(set_attr "type" "multi")])
20930
 
20931
(define_insn "stack_tls_protect_test_di"
20932
  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20933
        (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20934
                     (match_operand:DI 2 "const_int_operand" "i")]
20935
                    UNSPEC_SP_TLS_TEST))
20936
   (clobber (match_scratch:DI 3 "=r"))]
20937
  "TARGET_64BIT"
20938
  {
20939
     /* The kernel uses a different segment register for performance reasons; a
20940
        system call would not have to trash the userspace segment register,
20941
        which would be expensive */
20942
     if (ix86_cmodel != CM_KERNEL)
20943
        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20944
     else
20945
        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20946
  }
20947
  [(set_attr "type" "multi")])
20948
 
20949
(include "sse.md")
20950
(include "mmx.md")
20951
(include "sync.md")

powered by: WebSVN 2.1.0

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