254cd98a86d6837dfd2bbb0c5fae2c864339893a
[oota-llvm.git] / lib / Target / X86 / X86InstrInfo.td
1 //===- X86InstrInfo.td - Describe the X86 Instruction Set -------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 instruction set, defining the instructions, and
11 // properties of the instructions which are needed for code generation, machine
12 // code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16 //===----------------------------------------------------------------------===//
17 // X86 specific DAG Nodes.
18 //
19
20 def SDTIntShiftDOp: SDTypeProfile<1, 3,
21                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22                                    SDTCisInt<0>, SDTCisInt<3>]>;
23
24 def SDTX86CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
25
26 def SDTX86Cmov    : SDTypeProfile<1, 3,
27                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
28                                    SDTCisVT<3, i8>]>;
29
30 def SDTX86BrCond  : SDTypeProfile<0, 2,
31                                   [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>;
32
33 def SDTX86SetCC   : SDTypeProfile<1, 1,
34                                   [SDTCisVT<0, i8>, SDTCisVT<1, i8>]>;
35
36 def SDTX86Ret     : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
37
38 def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
39 def SDT_X86CallSeqEnd   : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
40                                                 SDTCisVT<1, i32> ]>;
41
42 def SDT_X86Call   : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
43
44 def SDTX86FpGet   : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>;
45 def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
46
47 def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
48                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
49 def SDTX86Fst     : SDTypeProfile<0, 3, [SDTCisFP<0>,
50                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
51 def SDTX86Fild    : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisPtrTy<1>,
52                                          SDTCisVT<2, OtherVT>]>;
53 def SDTX86FpToIMem: SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
54
55 def SDTX86RepStr  : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
56
57 def SDTX86RdTsc   : SDTypeProfile<0, 0, []>;
58
59 def X86addflag : SDNode<"X86ISD::ADD_FLAG", SDTIntBinOp ,
60                         [SDNPCommutative, SDNPAssociative, SDNPOutFlag]>;
61 def X86subflag : SDNode<"X86ISD::SUB_FLAG", SDTIntBinOp,
62                         [SDNPOutFlag]>;
63 def X86adc     : SDNode<"X86ISD::ADC" ,     SDTIntBinOp ,
64                         [SDNPCommutative, SDNPAssociative, SDNPInFlag]>;
65 def X86sbb     : SDNode<"X86ISD::SBB" ,     SDTIntBinOp,
66                         [SDNPInFlag]>;
67
68 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
69 def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
70
71 def X86fand    : SDNode<"X86ISD::FAND",     SDTFPBinOp,
72                         [SDNPCommutative, SDNPAssociative]>;
73 def X86fxor    : SDNode<"X86ISD::FXOR",     SDTFPBinOp,
74                         [SDNPCommutative, SDNPAssociative]>;
75
76 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest,
77                         [SDNPOutFlag]>;
78 def X86test    : SDNode<"X86ISD::TEST",     SDTX86CmpTest,
79                         [SDNPOutFlag]>;
80
81 def X86cmov    : SDNode<"X86ISD::CMOV",     SDTX86Cmov,    
82                         [SDNPInFlag, SDNPOutFlag]>;
83 def X86brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,
84                         [SDNPHasChain, SDNPInFlag]>;
85 def X86setcc   : SDNode<"X86ISD::SETCC",    SDTX86SetCC,
86                         [SDNPInFlag, SDNPOutFlag]>;
87
88 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
89                         [SDNPHasChain, SDNPOptInFlag]>;
90
91 def X86callseq_start :
92                  SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
93                         [SDNPHasChain]>;
94 def X86callseq_end :
95                  SDNode<"ISD::CALLSEQ_END",   SDT_X86CallSeqEnd,
96                         [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
97
98 def X86call    : SDNode<"X86ISD::CALL",     SDT_X86Call,
99                         [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
100
101 def X86fpget   : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
102                         [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
103 def X86fpset   : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
104                         [SDNPHasChain, SDNPOutFlag]>;
105
106 def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,
107                         [SDNPHasChain]>;
108 def X86fst     : SDNode<"X86ISD::FST",      SDTX86Fst,
109                         [SDNPHasChain, SDNPInFlag]>;
110 def X86fild    : SDNode<"X86ISD::FILD",     SDTX86Fild,
111                         [SDNPHasChain]>;
112 def X86fildflag: SDNode<"X86ISD::FILD_FLAG",SDTX86Fild,
113                         [SDNPHasChain, SDNPOutFlag]>;
114 def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
115                         [SDNPHasChain]>;
116 def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
117                         [SDNPHasChain]>;
118 def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
119                         [SDNPHasChain]>;
120
121 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
122                         [SDNPHasChain, SDNPInFlag]>;
123 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
124                         [SDNPHasChain, SDNPInFlag]>;
125
126 def X86rdtsc   : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
127                         [SDNPHasChain, SDNPOutFlag]>;
128
129 def X86loadp  : SDNode<"X86ISD::LOAD_PACK", SDTLoad, 
130                         [SDNPHasChain]>;
131
132 //===----------------------------------------------------------------------===//
133 // X86 Operand Definitions.
134 //
135
136 // *mem - Operand definitions for the funky X86 addressing mode operands.
137 //
138 class X86MemOperand<string printMethod> : Operand<i32> {
139   let PrintMethod = printMethod;
140   let NumMIOperands = 4;
141   let MIOperandInfo = (ops R32, i8imm, R32, i32imm);
142 }
143
144 def i8mem   : X86MemOperand<"printi8mem">;
145 def i16mem  : X86MemOperand<"printi16mem">;
146 def i32mem  : X86MemOperand<"printi32mem">;
147 def i64mem  : X86MemOperand<"printi64mem">;
148 def f32mem  : X86MemOperand<"printf32mem">;
149 def f64mem  : X86MemOperand<"printf64mem">;
150 def f128mem : X86MemOperand<"printf128mem">;
151
152 def SSECC : Operand<i8> {
153   let PrintMethod = "printSSECC";
154 }
155
156 // A couple of more descriptive operand definitions.
157 // 16-bits but only 8 bits are significant.
158 def i16i8imm  : Operand<i16>;
159 // 32-bits but only 8 bits are significant.
160 def i32i8imm  : Operand<i32>;
161
162 // PCRelative calls need special operand formatting.
163 let PrintMethod = "printCallOperand" in
164   def calltarget : Operand<i32>;
165
166 // Branch targets have OtherVT type.
167 def brtarget : Operand<OtherVT>;
168
169 //===----------------------------------------------------------------------===//
170 // X86 Complex Pattern Definitions.
171 //
172
173 // Define X86 specific addressing mode.
174 def addr    : ComplexPattern<i32, 4, "SelectAddr", []>;
175 def leaaddr : ComplexPattern<i32, 4, "SelectLEAAddr",
176                              [add, frameindex, constpool]>;
177
178 //===----------------------------------------------------------------------===//
179 // X86 Instruction Format Definitions.
180 //
181
182 // Format specifies the encoding used by the instruction.  This is part of the
183 // ad-hoc solution used to emit machine instruction encodings by our machine
184 // code emitter.
185 class Format<bits<6> val> {
186   bits<6> Value = val;
187 }
188
189 def Pseudo     : Format<0>; def RawFrm     : Format<1>;
190 def AddRegFrm  : Format<2>; def MRMDestReg : Format<3>;
191 def MRMDestMem : Format<4>; def MRMSrcReg  : Format<5>;
192 def MRMSrcMem  : Format<6>;
193 def MRM0r  : Format<16>; def MRM1r  : Format<17>; def MRM2r  : Format<18>;
194 def MRM3r  : Format<19>; def MRM4r  : Format<20>; def MRM5r  : Format<21>;
195 def MRM6r  : Format<22>; def MRM7r  : Format<23>;
196 def MRM0m  : Format<24>; def MRM1m  : Format<25>; def MRM2m  : Format<26>;
197 def MRM3m  : Format<27>; def MRM4m  : Format<28>; def MRM5m  : Format<29>;
198 def MRM6m  : Format<30>; def MRM7m  : Format<31>;
199 def MRMInitReg : Format<32>;
200
201 //===----------------------------------------------------------------------===//
202 // X86 Instruction Predicate Definitions.
203 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
204 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
205 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
206 def FPStack : Predicate<"!Subtarget->hasSSE2()">;
207
208 //===----------------------------------------------------------------------===//
209 // X86 specific pattern fragments.
210 //
211
212 // ImmType - This specifies the immediate type used by an instruction. This is
213 // part of the ad-hoc solution used to emit machine instruction encodings by our
214 // machine code emitter.
215 class ImmType<bits<2> val> {
216   bits<2> Value = val;
217 }
218 def NoImm  : ImmType<0>;
219 def Imm8   : ImmType<1>;
220 def Imm16  : ImmType<2>;
221 def Imm32  : ImmType<3>;
222
223 // FPFormat - This specifies what form this FP instruction has.  This is used by
224 // the Floating-Point stackifier pass.
225 class FPFormat<bits<3> val> {
226   bits<3> Value = val;
227 }
228 def NotFP      : FPFormat<0>;
229 def ZeroArgFP  : FPFormat<1>;
230 def OneArgFP   : FPFormat<2>;
231 def OneArgFPRW : FPFormat<3>;
232 def TwoArgFP   : FPFormat<4>;
233 def CompareFP  : FPFormat<5>;
234 def CondMovFP  : FPFormat<6>;
235 def SpecialFP  : FPFormat<7>;
236
237
238 class X86Inst<bits<8> opcod, Format f, ImmType i, dag ops, string AsmStr>
239   : Instruction {
240   let Namespace = "X86";
241
242   bits<8> Opcode = opcod;
243   Format Form = f;
244   bits<6> FormBits = Form.Value;
245   ImmType ImmT = i;
246   bits<2> ImmTypeBits = ImmT.Value;
247
248   dag OperandList = ops;
249   string AsmString = AsmStr;
250
251   //
252   // Attributes specific to X86 instructions...
253   //
254   bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix?
255
256   bits<4> Prefix = 0;       // Which prefix byte does this inst have?
257   FPFormat FPForm;          // What flavor of FP instruction is this?
258   bits<3> FPFormBits = 0;
259 }
260
261 class Imp<list<Register> uses, list<Register> defs> {
262   list<Register> Uses = uses;
263   list<Register> Defs = defs;
264 }
265
266
267 // Prefix byte classes which are used to indicate to the ad-hoc machine code
268 // emitter that various prefix bytes are required.
269 class OpSize { bit hasOpSizePrefix = 1; }
270 class TB     { bits<4> Prefix = 1; }
271 class REP    { bits<4> Prefix = 2; }
272 class D8     { bits<4> Prefix = 3; }
273 class D9     { bits<4> Prefix = 4; }
274 class DA     { bits<4> Prefix = 5; }
275 class DB     { bits<4> Prefix = 6; }
276 class DC     { bits<4> Prefix = 7; }
277 class DD     { bits<4> Prefix = 8; }
278 class DE     { bits<4> Prefix = 9; }
279 class DF     { bits<4> Prefix = 10; }
280 class XD     { bits<4> Prefix = 11; }
281 class XS     { bits<4> Prefix = 12; }
282
283
284 //===----------------------------------------------------------------------===//
285 // Pattern fragments...
286 //
287
288 // X86 specific condition code. These correspond to CondCode in
289 // X86ISelLowering.h. They must be kept in synch.
290 def X86_COND_A   : PatLeaf<(i8 0)>;
291 def X86_COND_AE  : PatLeaf<(i8 1)>;
292 def X86_COND_B   : PatLeaf<(i8 2)>;
293 def X86_COND_BE  : PatLeaf<(i8 3)>;
294 def X86_COND_E   : PatLeaf<(i8 4)>;
295 def X86_COND_G   : PatLeaf<(i8 5)>;
296 def X86_COND_GE  : PatLeaf<(i8 6)>;
297 def X86_COND_L   : PatLeaf<(i8 7)>;
298 def X86_COND_LE  : PatLeaf<(i8 8)>;
299 def X86_COND_NE  : PatLeaf<(i8 9)>;
300 def X86_COND_NO  : PatLeaf<(i8 10)>;
301 def X86_COND_NP  : PatLeaf<(i8 11)>;
302 def X86_COND_NS  : PatLeaf<(i8 12)>;
303 def X86_COND_O   : PatLeaf<(i8 13)>;
304 def X86_COND_P   : PatLeaf<(i8 14)>;
305 def X86_COND_S   : PatLeaf<(i8 15)>;
306
307 def i16immSExt8  : PatLeaf<(i16 imm), [{
308   // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit
309   // sign extended field.
310   return (int)N->getValue() == (signed char)N->getValue();
311 }]>;
312
313 def i32immSExt8  : PatLeaf<(i32 imm), [{
314   // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
315   // sign extended field.
316   return (int)N->getValue() == (signed char)N->getValue();
317 }]>;
318
319 def i16immZExt8  : PatLeaf<(i16 imm), [{
320   // i16immZExt8 predicate - True if the 16-bit immediate fits in a 8-bit zero
321   // extended field.
322   return (unsigned)N->getValue() == (unsigned char)N->getValue();
323 }]>;
324
325 def fp32imm0 : PatLeaf<(f32 fpimm), [{
326   return N->isExactlyValue(+0.0);
327 }]>;
328
329 def fp64imm0 : PatLeaf<(f64 fpimm), [{
330   return N->isExactlyValue(+0.0);
331 }]>;
332
333 def fp64immneg0 : PatLeaf<(f64 fpimm), [{
334   return N->isExactlyValue(-0.0);
335 }]>;
336
337 def fp64imm1 : PatLeaf<(f64 fpimm), [{
338   return N->isExactlyValue(+1.0);
339 }]>;
340
341 def fp64immneg1 : PatLeaf<(f64 fpimm), [{
342   return N->isExactlyValue(-1.0);
343 }]>;
344
345 // Helper fragments for loads.
346 def loadi8  : PatFrag<(ops node:$ptr), (i8  (load node:$ptr))>;
347 def loadi16 : PatFrag<(ops node:$ptr), (i16 (load node:$ptr))>;
348 def loadi32 : PatFrag<(ops node:$ptr), (i32 (load node:$ptr))>;
349 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
350 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
351
352 def sextloadi16i1  : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i1))>;
353 def sextloadi32i1  : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i1))>;
354 def sextloadi16i8  : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i8))>;
355 def sextloadi32i8  : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i8))>;
356 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i16))>;
357
358 def zextloadi8i1   : PatFrag<(ops node:$ptr), (i8  (zextload node:$ptr, i1))>;
359 def zextloadi16i1  : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i1))>;
360 def zextloadi32i1  : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i1))>;
361 def zextloadi16i8  : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>;
362 def zextloadi32i8  : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
363 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
364
365 def extloadi8i1    : PatFrag<(ops node:$ptr), (i8  (extload node:$ptr, i1))>;
366 def extloadf64f32  : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>;
367
368 def X86loadpf32    : PatFrag<(ops node:$ptr), (f32  (X86loadp node:$ptr))>;
369 def X86loadpf64    : PatFrag<(ops node:$ptr), (f64  (X86loadp node:$ptr))>;
370
371 //===----------------------------------------------------------------------===//
372 // Instruction templates...
373
374 class I<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
375   : X86Inst<o, f, NoImm, ops, asm> {
376   let Pattern = pattern;
377 }
378 class Ii8 <bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
379   : X86Inst<o, f, Imm8 , ops, asm> {
380   let Pattern = pattern;
381 }
382 class Ii16<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
383   : X86Inst<o, f, Imm16, ops, asm> {
384   let Pattern = pattern;
385 }
386 class Ii32<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
387   : X86Inst<o, f, Imm32, ops, asm> {
388   let Pattern = pattern;
389 }
390
391 //===----------------------------------------------------------------------===//
392 // Instruction list...
393 //
394
395 def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
396                          [(X86callseq_start imm:$amt)]>;
397 def ADJCALLSTACKUP   : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
398                          "#ADJCALLSTACKUP",
399                          [(X86callseq_end imm:$amt1, imm:$amt2)]>;
400 def IMPLICIT_USE     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
401 def IMPLICIT_DEF     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
402 def IMPLICIT_DEF_R8  : I<0, Pseudo, (ops R8:$dst),
403                          "#IMPLICIT_DEF $dst",
404                          [(set R8:$dst, (undef))]>;
405 def IMPLICIT_DEF_R16  : I<0, Pseudo, (ops R16:$dst),
406                          "#IMPLICIT_DEF $dst",
407                          [(set R16:$dst, (undef))]>;
408 def IMPLICIT_DEF_R32  : I<0, Pseudo, (ops R32:$dst),
409                          "#IMPLICIT_DEF $dst",
410                          [(set R32:$dst, (undef))]>;
411 def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst),
412                          "#IMPLICIT_DEF $dst",
413                          [(set FR32:$dst, (undef))]>, Requires<[HasSSE2]>;
414 def IMPLICIT_DEF_FR64 : I<0, Pseudo, (ops FR64:$dst),
415                          "#IMPLICIT_DEF $dst",
416                          [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>;
417
418
419 // CMOV* - Used to implement the SSE SELECT DAG operation.  Expanded by the
420 // scheduler into a branch sequence.
421 let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
422   def CMOV_FR32 : I<0, Pseudo,
423                     (ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond),
424                     "#CMOV_FR32 PSEUDO!",
425                     [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond))]>;
426   def CMOV_FR64 : I<0, Pseudo,
427                     (ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond),
428                     "#CMOV_FR64 PSEUDO!",
429                     [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond))]>;
430 }
431
432 let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
433   def FP_TO_INT16_IN_MEM : I<0, Pseudo,
434                             (ops i16mem:$dst, RFP:$src),
435                            "#FP_TO_INT16_IN_MEM PSEUDO!",
436                            [(X86fp_to_i16mem RFP:$src, addr:$dst)]>;
437   def FP_TO_INT32_IN_MEM : I<0, Pseudo,
438                             (ops i32mem:$dst, RFP:$src),
439                            "#FP_TO_INT32_IN_MEM PSEUDO!",
440                            [(X86fp_to_i32mem RFP:$src, addr:$dst)]>;
441   def FP_TO_INT64_IN_MEM : I<0, Pseudo,
442                             (ops i64mem:$dst, RFP:$src),
443                            "#FP_TO_INT64_IN_MEM PSEUDO!",
444                            [(X86fp_to_i64mem RFP:$src, addr:$dst)]>;
445 }
446
447
448 let isTerminator = 1 in
449   let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
450     def FP_REG_KILL  : I<0, Pseudo, (ops), "#FP_REG_KILL", []>;
451
452
453 // Nop
454 def NOOP : I<0x90, RawFrm, (ops), "nop", []>;
455
456 //===----------------------------------------------------------------------===//
457 //  Control Flow Instructions...
458 //
459
460 // Return instructions.
461 let isTerminator = 1, isReturn = 1, isBarrier = 1,
462     hasCtrlDep = 1, noResults = 1 in {
463   def RET    : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
464   def RETI   : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
465                     [(X86retflag imm:$amt)]>;
466 }
467
468 // All branches are RawFrm, Void, Branch, and Terminators
469 let isBranch = 1, isTerminator = 1, noResults = 1 in
470   class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
471         I<opcode, RawFrm, ops, asm, pattern>;
472
473 // Conditional branches
474 let isBarrier = 1 in
475   def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
476
477 def JE  : IBr<0x84, (ops brtarget:$dst), "je $dst",
478               [(X86brcond bb:$dst, X86_COND_E)]>, TB;
479 def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
480               [(X86brcond bb:$dst, X86_COND_NE)]>, TB;
481 def JL  : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
482               [(X86brcond bb:$dst, X86_COND_L)]>, TB;
483 def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
484               [(X86brcond bb:$dst, X86_COND_LE)]>, TB;
485 def JG  : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
486               [(X86brcond bb:$dst, X86_COND_G)]>, TB;
487 def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
488               [(X86brcond bb:$dst, X86_COND_GE)]>, TB;
489
490 def JB  : IBr<0x82, (ops brtarget:$dst), "jb $dst",
491               [(X86brcond bb:$dst, X86_COND_B)]>, TB;
492 def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
493               [(X86brcond bb:$dst, X86_COND_BE)]>, TB;
494 def JA  : IBr<0x87, (ops brtarget:$dst), "ja $dst",
495               [(X86brcond bb:$dst, X86_COND_A)]>, TB;
496 def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
497               [(X86brcond bb:$dst, X86_COND_AE)]>, TB;
498
499 def JS  : IBr<0x88, (ops brtarget:$dst), "js $dst",
500               [(X86brcond bb:$dst, X86_COND_S)]>, TB;
501 def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst",
502               [(X86brcond bb:$dst, X86_COND_NS)]>, TB;
503 def JP  : IBr<0x8A, (ops brtarget:$dst), "jp $dst",
504               [(X86brcond bb:$dst, X86_COND_P)]>, TB;
505 def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst",
506               [(X86brcond bb:$dst, X86_COND_NP)]>, TB;
507 def JO  : IBr<0x80, (ops brtarget:$dst), "jo $dst",
508               [(X86brcond bb:$dst, X86_COND_O)]>, TB;
509 def JNO : IBr<0x81, (ops brtarget:$dst), "jno $dst",
510               [(X86brcond bb:$dst, X86_COND_NO)]>, TB;
511
512 //===----------------------------------------------------------------------===//
513 //  Call Instructions...
514 //
515 let isCall = 1, noResults = 1 in
516   // All calls clobber the non-callee saved registers...
517   let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
518               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
519     def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst",
520                       []>;
521     def CALL32r     : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst",
522                       [(X86call R32:$dst)]>;
523     def CALL32m     : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst",
524                       [(X86call (loadi32 addr:$dst))]>;
525   }
526
527 // Tail call stuff.
528 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
529   def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst  # TAIL CALL", []>;
530 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
531   def TAILJMPr : I<0xFF, MRM4r, (ops R32:$dst), "jmp {*}$dst  # TAIL CALL", []>;
532 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
533   def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
534                    "jmp {*}$dst  # TAIL CALL", []>;
535
536 // ADJSTACKPTRri - This is a standard ADD32ri instruction, identical in every
537 // way, except that it is marked as being a terminator.  This causes the epilog
538 // inserter to insert reloads of callee saved registers BEFORE this.  We need
539 // this until we have a more accurate way of tracking where the stack pointer is
540 // within a function.
541 let isTerminator = 1, isTwoAddress = 1 in
542   def ADJSTACKPTRri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
543                            "add{l} {$src2, $dst|$dst, $src2}", []>;
544
545 //===----------------------------------------------------------------------===//
546 //  Miscellaneous Instructions...
547 //
548 def LEAVE    : I<0xC9, RawFrm,
549                  (ops), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
550 def POP32r   : I<0x58, AddRegFrm,
551                  (ops R32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
552
553 let isTwoAddress = 1 in                               // R32 = bswap R32
554   def BSWAP32r : I<0xC8, AddRegFrm,
555                    (ops R32:$dst, R32:$src),
556                    "bswap{l} $dst", 
557                    [(set R32:$dst, (bswap R32:$src))]>, TB;
558
559 def XCHG8rr  : I<0x86, MRMDestReg,                    // xchg R8, R8
560                  (ops R8:$src1, R8:$src2),
561                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
562 def XCHG16rr : I<0x87, MRMDestReg,                    // xchg R16, R16
563                  (ops R16:$src1, R16:$src2),
564                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
565 def XCHG32rr : I<0x87, MRMDestReg,                    // xchg R32, R32
566                  (ops R32:$src1, R32:$src2),
567                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
568
569 def XCHG8mr  : I<0x86, MRMDestMem,
570                  (ops i8mem:$src1, R8:$src2),
571                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
572 def XCHG16mr : I<0x87, MRMDestMem,
573                  (ops i16mem:$src1, R16:$src2),
574                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
575 def XCHG32mr : I<0x87, MRMDestMem,
576                  (ops i32mem:$src1, R32:$src2),
577                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
578 def XCHG8rm  : I<0x86, MRMSrcMem,
579                  (ops R8:$src1, i8mem:$src2),
580                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
581 def XCHG16rm : I<0x87, MRMSrcMem,
582                  (ops R16:$src1, i16mem:$src2),
583                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
584 def XCHG32rm : I<0x87, MRMSrcMem,
585                  (ops R32:$src1, i32mem:$src2),
586                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
587
588 def LEA16r   : I<0x8D, MRMSrcMem,
589                  (ops R16:$dst, i32mem:$src),
590                  "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
591 def LEA32r   : I<0x8D, MRMSrcMem,
592                  (ops R32:$dst, i32mem:$src),
593                  "lea{l} {$src|$dst}, {$dst|$src}",
594                  [(set R32:$dst, leaaddr:$src)]>;
595
596 def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}",
597                   [(X86rep_movs i8)]>,
598                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
599 def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}",
600                   [(X86rep_movs i16)]>,
601                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
602 def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}",
603                   [(X86rep_movs i32)]>,
604                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
605
606 def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}",
607                   [(X86rep_stos i8)]>,
608                 Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
609 def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}",
610                   [(X86rep_stos i16)]>,
611                 Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
612 def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
613                   [(X86rep_stos i32)]>,
614                 Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
615
616
617 //===----------------------------------------------------------------------===//
618 //  Input/Output Instructions...
619 //
620 def IN8rr  : I<0xEC, RawFrm, (ops),
621                "in{b} {%dx, %al|%AL, %DX}",
622                [(set AL, (readport DX))]>,  Imp<[DX], [AL]>;
623 def IN16rr : I<0xED, RawFrm, (ops),
624                "in{w} {%dx, %ax|%AX, %DX}",
625                [(set AX, (readport DX))]>,  Imp<[DX], [AX]>, OpSize;
626 def IN32rr : I<0xED, RawFrm, (ops),
627                "in{l} {%dx, %eax|%EAX, %DX}",
628                [(set EAX, (readport DX))]>, Imp<[DX],[EAX]>;
629
630 def IN8ri  : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
631                   "in{b} {$port, %al|%AL, $port}",
632                  [(set AL, (readport i16immZExt8:$port))]>,
633              Imp<[], [AL]>;
634 def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
635                   "in{w} {$port, %ax|%AX, $port}",
636                  [(set AX, (readport i16immZExt8:$port))]>,
637              Imp<[], [AX]>, OpSize;
638 def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
639                   "in{l} {$port, %eax|%EAX, $port}",
640                  [(set EAX, (readport i16immZExt8:$port))]>,
641              Imp<[],[EAX]>;
642
643 def OUT8rr  : I<0xEE, RawFrm, (ops),
644                 "out{b} {%al, %dx|%DX, %AL}",
645                 [(writeport AL, DX)]>,  Imp<[DX,  AL], []>;
646 def OUT16rr : I<0xEF, RawFrm, (ops),
647                 "out{w} {%ax, %dx|%DX, %AX}",
648                 [(writeport AX, DX)]>,  Imp<[DX,  AX], []>, OpSize;
649 def OUT32rr : I<0xEF, RawFrm, (ops),
650                 "out{l} {%eax, %dx|%DX, %EAX}",
651                 [(writeport EAX, DX)]>, Imp<[DX, EAX], []>;
652
653 def OUT8ir  : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
654                    "out{b} {%al, $port|$port, %AL}",
655                    [(writeport AL, i16immZExt8:$port)]>,
656               Imp<[AL], []>;
657 def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
658                    "out{w} {%ax, $port|$port, %AX}",
659                    [(writeport AX, i16immZExt8:$port)]>,
660               Imp<[AX], []>, OpSize;
661 def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
662                    "out{l} {%eax, $port|$port, %EAX}",
663                    [(writeport EAX, i16immZExt8:$port)]>,
664               Imp<[EAX], []>;
665
666 //===----------------------------------------------------------------------===//
667 //  Move Instructions...
668 //
669 def MOV8rr  : I<0x88, MRMDestReg, (ops R8 :$dst, R8 :$src),
670                 "mov{b} {$src, $dst|$dst, $src}", []>;
671 def MOV16rr : I<0x89, MRMDestReg, (ops R16:$dst, R16:$src),
672                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
673 def MOV32rr : I<0x89, MRMDestReg, (ops R32:$dst, R32:$src),
674                 "mov{l} {$src, $dst|$dst, $src}", []>;
675 def MOV8ri  : Ii8 <0xB0, AddRegFrm, (ops R8 :$dst, i8imm :$src),
676                    "mov{b} {$src, $dst|$dst, $src}",
677                    [(set R8:$dst, imm:$src)]>;
678 def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src),
679                    "mov{w} {$src, $dst|$dst, $src}",
680                    [(set R16:$dst, imm:$src)]>, OpSize;
681 def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src),
682                    "mov{l} {$src, $dst|$dst, $src}",
683                    [(set R32:$dst, imm:$src)]>;
684 def MOV8mi  : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
685                    "mov{b} {$src, $dst|$dst, $src}",
686                    [(store (i8 imm:$src), addr:$dst)]>;
687 def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src),
688                    "mov{w} {$src, $dst|$dst, $src}",
689                    [(store (i16 imm:$src), addr:$dst)]>, OpSize;
690 def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src),
691                    "mov{l} {$src, $dst|$dst, $src}",
692                    [(store (i32 imm:$src), addr:$dst)]>;
693
694 def MOV8rm  : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src),
695                 "mov{b} {$src, $dst|$dst, $src}",
696                 [(set R8:$dst, (load addr:$src))]>;
697 def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src),
698                 "mov{w} {$src, $dst|$dst, $src}",
699                 [(set R16:$dst, (load addr:$src))]>, OpSize;
700 def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src),
701                 "mov{l} {$src, $dst|$dst, $src}",
702                 [(set R32:$dst, (load addr:$src))]>;
703
704 def MOV8mr  : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src),
705                 "mov{b} {$src, $dst|$dst, $src}",
706                 [(store R8:$src, addr:$dst)]>;
707 def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16:$src),
708                 "mov{w} {$src, $dst|$dst, $src}",
709                 [(store R16:$src, addr:$dst)]>, OpSize;
710 def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src),
711                 "mov{l} {$src, $dst|$dst, $src}",
712                 [(store R32:$src, addr:$dst)]>;
713                 
714 // Pseudo-instructions that map movr0 to xor.
715 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
716 def MOV8r0   : I<0x30, MRMInitReg, (ops R8 :$dst),
717                  "xor{b} $dst, $dst",
718                  [(set R8:$dst, 0)]>;
719 def MOV16r0  : I<0x31, MRMInitReg,  (ops R16:$dst), 
720                  "xor{w} $dst, $dst",
721                  [(set R16:$dst, 0)]>, OpSize;
722 def MOV32r0  : I<0x31, MRMInitReg,  (ops R32:$dst), 
723                  "xor{l} $dst, $dst",
724                  [(set R32:$dst, 0)]>;
725
726 //===----------------------------------------------------------------------===//
727 //  Fixed-Register Multiplication and Division Instructions...
728 //
729
730 // Extra precision multiplication
731 def MUL8r  : I<0xF6, MRM4r, (ops R8:$src), "mul{b} $src",
732                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
733                // This probably ought to be moved to a def : Pat<> if the
734                // syntax can be accepted.
735                [(set AL, (mul AL, R8:$src))]>,
736              Imp<[AL],[AX]>;               // AL,AH = AL*R8
737 def MUL16r : I<0xF7, MRM4r, (ops R16:$src), "mul{w} $src", []>,
738              Imp<[AX],[AX,DX]>, OpSize;    // AX,DX = AX*R16
739 def MUL32r : I<0xF7, MRM4r, (ops R32:$src), "mul{l} $src", []>,
740              Imp<[EAX],[EAX,EDX]>;         // EAX,EDX = EAX*R32
741 def MUL8m  : I<0xF6, MRM4m, (ops i8mem :$src),
742                "mul{b} $src",
743                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
744                // This probably ought to be moved to a def : Pat<> if the
745                // syntax can be accepted.
746                [(set AL, (mul AL, (loadi8 addr:$src)))]>,
747              Imp<[AL],[AX]>;          // AL,AH = AL*[mem8]
748 def MUL16m : I<0xF7, MRM4m, (ops i16mem:$src),
749                "mul{w} $src", []>, Imp<[AX],[AX,DX]>,
750                OpSize; // AX,DX = AX*[mem16]
751 def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src),
752                "mul{l} $src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
753
754 def IMUL8r  : I<0xF6, MRM5r, (ops R8:$src), "imul{b} $src", []>,
755               Imp<[AL],[AX]>;               // AL,AH = AL*R8
756 def IMUL16r : I<0xF7, MRM5r, (ops R16:$src), "imul{w} $src", []>,
757               Imp<[AX],[AX,DX]>, OpSize;    // AX,DX = AX*R16
758 def IMUL32r : I<0xF7, MRM5r, (ops R32:$src), "imul{l} $src", []>,
759               Imp<[EAX],[EAX,EDX]>;         // EAX,EDX = EAX*R32
760 def IMUL8m  : I<0xF6, MRM5m, (ops i8mem :$src),
761                 "imul{b} $src", []>, Imp<[AL],[AX]>;        // AL,AH = AL*[mem8]
762 def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src),
763                 "imul{w} $src", []>, Imp<[AX],[AX,DX]>,
764                 OpSize; // AX,DX = AX*[mem16]
765 def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src),
766                 "imul{l} $src", []>,
767                 Imp<[EAX],[EAX,EDX]>;  // EAX,EDX = EAX*[mem32]
768
769 // unsigned division/remainder
770 def DIV8r  : I<0xF6, MRM6r, (ops R8:$src),          // AX/r8 = AL,AH
771                "div{b} $src", []>, Imp<[AX],[AX]>;
772 def DIV16r : I<0xF7, MRM6r, (ops R16:$src),         // DX:AX/r16 = AX,DX
773                "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
774 def DIV32r : I<0xF7, MRM6r, (ops R32:$src),         // EDX:EAX/r32 = EAX,EDX
775                "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
776 def DIV8m  : I<0xF6, MRM6m, (ops i8mem:$src),       // AX/[mem8] = AL,AH
777                "div{b} $src", []>, Imp<[AX],[AX]>;
778 def DIV16m : I<0xF7, MRM6m, (ops i16mem:$src),      // DX:AX/[mem16] = AX,DX
779                "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
780 def DIV32m : I<0xF7, MRM6m, (ops i32mem:$src),      // EDX:EAX/[mem32] = EAX,EDX
781                "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
782
783 // Signed division/remainder.
784 def IDIV8r : I<0xF6, MRM7r, (ops R8:$src),          // AX/r8 = AL,AH
785                "idiv{b} $src", []>, Imp<[AX],[AX]>;
786 def IDIV16r: I<0xF7, MRM7r, (ops R16:$src),         // DX:AX/r16 = AX,DX
787                "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
788 def IDIV32r: I<0xF7, MRM7r, (ops R32:$src),         // EDX:EAX/r32 = EAX,EDX
789                "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
790 def IDIV8m : I<0xF6, MRM7m, (ops i8mem:$src),      // AX/[mem8] = AL,AH
791                "idiv{b} $src", []>, Imp<[AX],[AX]>;
792 def IDIV16m: I<0xF7, MRM7m, (ops i16mem:$src),     // DX:AX/[mem16] = AX,DX
793                "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
794 def IDIV32m: I<0xF7, MRM7m, (ops i32mem:$src),     // EDX:EAX/[mem32] = EAX,EDX
795                "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
796
797 // Sign-extenders for division.
798 def CBW : I<0x98, RawFrm, (ops),
799             "{cbtw|cbw}", []>, Imp<[AL],[AH]>;   // AX = signext(AL)
800 def CWD : I<0x99, RawFrm, (ops),
801             "{cwtd|cwd}", []>, Imp<[AX],[DX]>;   // DX:AX = signext(AX)
802 def CDQ : I<0x99, RawFrm, (ops),
803             "{cltd|cdq}", []>, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
804           
805
806 //===----------------------------------------------------------------------===//
807 //  Two address Instructions...
808 //
809 let isTwoAddress = 1 in {
810
811 // Conditional moves
812 def CMOVB16rr : I<0x42, MRMSrcReg,       // if <u, R16 = R16
813                   (ops R16:$dst, R16:$src1, R16:$src2),
814                   "cmovb {$src2, $dst|$dst, $src2}",
815                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
816                                    X86_COND_B))]>,
817                   TB, OpSize;
818 def CMOVB16rm : I<0x42, MRMSrcMem,       // if <u, R16 = [mem16]
819                   (ops R16:$dst, R16:$src1, i16mem:$src2),
820                   "cmovb {$src2, $dst|$dst, $src2}",
821                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
822                                    X86_COND_B))]>,
823                   TB, OpSize;
824 def CMOVB32rr : I<0x42, MRMSrcReg,       // if <u, R32 = R32
825                   (ops R32:$dst, R32:$src1, R32:$src2),
826                   "cmovb {$src2, $dst|$dst, $src2}",
827                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
828                                    X86_COND_B))]>,
829                    TB;
830 def CMOVB32rm : I<0x42, MRMSrcMem,       // if <u, R32 = [mem32]
831                   (ops R32:$dst, R32:$src1, i32mem:$src2),
832                   "cmovb {$src2, $dst|$dst, $src2}",
833                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
834                                    X86_COND_B))]>,
835                    TB;
836
837 def CMOVAE16rr: I<0x43, MRMSrcReg,       // if >=u, R16 = R16
838                   (ops R16:$dst, R16:$src1, R16:$src2),
839                   "cmovae {$src2, $dst|$dst, $src2}",
840                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
841                                    X86_COND_AE))]>,
842                    TB, OpSize;
843 def CMOVAE16rm: I<0x43, MRMSrcMem,       // if >=u, R16 = [mem16]
844                   (ops R16:$dst, R16:$src1, i16mem:$src2),
845                   "cmovae {$src2, $dst|$dst, $src2}",
846                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
847                                    X86_COND_AE))]>,
848                    TB, OpSize;
849 def CMOVAE32rr: I<0x43, MRMSrcReg,       // if >=u, R32 = R32
850                   (ops R32:$dst, R32:$src1, R32:$src2),
851                   "cmovae {$src2, $dst|$dst, $src2}",
852                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
853                                    X86_COND_AE))]>,
854                    TB;
855 def CMOVAE32rm: I<0x43, MRMSrcMem,       // if >=u, R32 = [mem32]
856                   (ops R32:$dst, R32:$src1, i32mem:$src2),
857                   "cmovae {$src2, $dst|$dst, $src2}",
858                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
859                                    X86_COND_AE))]>,
860                    TB;
861
862 def CMOVE16rr : I<0x44, MRMSrcReg,       // if ==, R16 = R16
863                   (ops R16:$dst, R16:$src1, R16:$src2),
864                   "cmove {$src2, $dst|$dst, $src2}",
865                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
866                                    X86_COND_E))]>,
867                    TB, OpSize;
868 def CMOVE16rm : I<0x44, MRMSrcMem,       // if ==, R16 = [mem16]
869                   (ops R16:$dst, R16:$src1, i16mem:$src2),
870                   "cmove {$src2, $dst|$dst, $src2}",
871                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
872                                    X86_COND_E))]>,
873                    TB, OpSize;
874 def CMOVE32rr : I<0x44, MRMSrcReg,       // if ==, R32 = R32
875                   (ops R32:$dst, R32:$src1, R32:$src2),
876                   "cmove {$src2, $dst|$dst, $src2}",
877                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
878                                    X86_COND_E))]>,
879                    TB;
880 def CMOVE32rm : I<0x44, MRMSrcMem,       // if ==, R32 = [mem32]
881                   (ops R32:$dst, R32:$src1, i32mem:$src2),
882                   "cmove {$src2, $dst|$dst, $src2}",
883                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
884                                    X86_COND_E))]>,
885                    TB;
886
887 def CMOVNE16rr: I<0x45, MRMSrcReg,       // if !=, R16 = R16
888                   (ops R16:$dst, R16:$src1, R16:$src2),
889                   "cmovne {$src2, $dst|$dst, $src2}",
890                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
891                                    X86_COND_NE))]>,
892                    TB, OpSize;
893 def CMOVNE16rm: I<0x45, MRMSrcMem,       // if !=, R16 = [mem16]
894                   (ops R16:$dst, R16:$src1, i16mem:$src2),
895                   "cmovne {$src2, $dst|$dst, $src2}",
896                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
897                                    X86_COND_NE))]>,
898                    TB, OpSize;
899 def CMOVNE32rr: I<0x45, MRMSrcReg,       // if !=, R32 = R32
900                   (ops R32:$dst, R32:$src1, R32:$src2),
901                   "cmovne {$src2, $dst|$dst, $src2}",
902                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
903                                    X86_COND_NE))]>,
904                    TB;
905 def CMOVNE32rm: I<0x45, MRMSrcMem,       // if !=, R32 = [mem32]
906                   (ops R32:$dst, R32:$src1, i32mem:$src2),
907                   "cmovne {$src2, $dst|$dst, $src2}",
908                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
909                                    X86_COND_NE))]>,
910                    TB;
911
912 def CMOVBE16rr: I<0x46, MRMSrcReg,       // if <=u, R16 = R16
913                   (ops R16:$dst, R16:$src1, R16:$src2),
914                   "cmovbe {$src2, $dst|$dst, $src2}",
915                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
916                                    X86_COND_BE))]>,
917                    TB, OpSize;
918 def CMOVBE16rm: I<0x46, MRMSrcMem,       // if <=u, R16 = [mem16]
919                   (ops R16:$dst, R16:$src1, i16mem:$src2),
920                   "cmovbe {$src2, $dst|$dst, $src2}",
921                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
922                                    X86_COND_BE))]>,
923                    TB, OpSize;
924 def CMOVBE32rr: I<0x46, MRMSrcReg,       // if <=u, R32 = R32
925                   (ops R32:$dst, R32:$src1, R32:$src2),
926                   "cmovbe {$src2, $dst|$dst, $src2}",
927                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
928                                    X86_COND_BE))]>,
929                    TB;
930 def CMOVBE32rm: I<0x46, MRMSrcMem,       // if <=u, R32 = [mem32]
931                   (ops R32:$dst, R32:$src1, i32mem:$src2),
932                   "cmovbe {$src2, $dst|$dst, $src2}",
933                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
934                                    X86_COND_BE))]>,
935                    TB;
936
937 def CMOVA16rr : I<0x47, MRMSrcReg,       // if >u, R16 = R16
938                   (ops R16:$dst, R16:$src1, R16:$src2),
939                   "cmova {$src2, $dst|$dst, $src2}",
940                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
941                                    X86_COND_A))]>,
942                    TB, OpSize;
943 def CMOVA16rm : I<0x47, MRMSrcMem,       // if >u, R16 = [mem16]
944                   (ops R16:$dst, R16:$src1, i16mem:$src2),
945                   "cmova {$src2, $dst|$dst, $src2}",
946                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
947                                    X86_COND_A))]>,
948                    TB, OpSize;
949 def CMOVA32rr : I<0x47, MRMSrcReg,       // if >u, R32 = R32
950                   (ops R32:$dst, R32:$src1, R32:$src2),
951                   "cmova {$src2, $dst|$dst, $src2}",
952                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
953                                    X86_COND_A))]>,
954                    TB;
955 def CMOVA32rm : I<0x47, MRMSrcMem,       // if >u, R32 = [mem32]
956                   (ops R32:$dst, R32:$src1, i32mem:$src2),
957                   "cmova {$src2, $dst|$dst, $src2}",
958                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
959                                    X86_COND_A))]>,
960                    TB;
961
962 def CMOVL16rr : I<0x4C, MRMSrcReg,       // if <s, R16 = R16
963                   (ops R16:$dst, R16:$src1, R16:$src2),
964                   "cmovl {$src2, $dst|$dst, $src2}",
965                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
966                                    X86_COND_L))]>,
967                    TB, OpSize;
968 def CMOVL16rm : I<0x4C, MRMSrcMem,       // if <s, R16 = [mem16]
969                   (ops R16:$dst, R16:$src1, i16mem:$src2),
970                   "cmovl {$src2, $dst|$dst, $src2}",
971                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
972                                    X86_COND_L))]>,
973                    TB, OpSize;
974 def CMOVL32rr : I<0x4C, MRMSrcReg,       // if <s, R32 = R32
975                   (ops R32:$dst, R32:$src1, R32:$src2),
976                   "cmovl {$src2, $dst|$dst, $src2}",
977                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
978                                    X86_COND_L))]>,
979                    TB;
980 def CMOVL32rm : I<0x4C, MRMSrcMem,       // if <s, R32 = [mem32]
981                   (ops R32:$dst, R32:$src1, i32mem:$src2),
982                   "cmovl {$src2, $dst|$dst, $src2}",
983                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
984                                    X86_COND_L))]>,
985                    TB;
986
987 def CMOVGE16rr: I<0x4D, MRMSrcReg,       // if >=s, R16 = R16
988                   (ops R16:$dst, R16:$src1, R16:$src2),
989                   "cmovge {$src2, $dst|$dst, $src2}",
990                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
991                                    X86_COND_GE))]>,
992                    TB, OpSize;
993 def CMOVGE16rm: I<0x4D, MRMSrcMem,       // if >=s, R16 = [mem16]
994                   (ops R16:$dst, R16:$src1, i16mem:$src2),
995                   "cmovge {$src2, $dst|$dst, $src2}",
996                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
997                                    X86_COND_GE))]>,
998                    TB, OpSize;
999 def CMOVGE32rr: I<0x4D, MRMSrcReg,       // if >=s, R32 = R32
1000                   (ops R32:$dst, R32:$src1, R32:$src2),
1001                   "cmovge {$src2, $dst|$dst, $src2}",
1002                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1003                                    X86_COND_GE))]>,
1004                    TB;
1005 def CMOVGE32rm: I<0x4D, MRMSrcMem,       // if >=s, R32 = [mem32]
1006                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1007                   "cmovge {$src2, $dst|$dst, $src2}",
1008                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1009                                    X86_COND_GE))]>,
1010                    TB;
1011
1012 def CMOVLE16rr: I<0x4E, MRMSrcReg,       // if <=s, R16 = R16
1013                   (ops R16:$dst, R16:$src1, R16:$src2),
1014                   "cmovle {$src2, $dst|$dst, $src2}",
1015                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1016                                    X86_COND_LE))]>,
1017                    TB, OpSize;
1018 def CMOVLE16rm: I<0x4E, MRMSrcMem,       // if <=s, R16 = [mem16]
1019                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1020                   "cmovle {$src2, $dst|$dst, $src2}",
1021                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1022                                    X86_COND_LE))]>,
1023                    TB, OpSize;
1024 def CMOVLE32rr: I<0x4E, MRMSrcReg,       // if <=s, R32 = R32
1025                   (ops R32:$dst, R32:$src1, R32:$src2),
1026                   "cmovle {$src2, $dst|$dst, $src2}",
1027                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1028                                    X86_COND_LE))]>,
1029                    TB;
1030 def CMOVLE32rm: I<0x4E, MRMSrcMem,       // if <=s, R32 = [mem32]
1031                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1032                   "cmovle {$src2, $dst|$dst, $src2}",
1033                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1034                                    X86_COND_LE))]>,
1035                    TB;
1036
1037 def CMOVG16rr : I<0x4F, MRMSrcReg,       // if >s, R16 = R16
1038                   (ops R16:$dst, R16:$src1, R16:$src2),
1039                   "cmovg {$src2, $dst|$dst, $src2}",
1040                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1041                                    X86_COND_G))]>,
1042                    TB, OpSize;
1043 def CMOVG16rm : I<0x4F, MRMSrcMem,       // if >s, R16 = [mem16]
1044                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1045                   "cmovg {$src2, $dst|$dst, $src2}",
1046                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1047                                    X86_COND_G))]>,
1048                    TB, OpSize;
1049 def CMOVG32rr : I<0x4F, MRMSrcReg,       // if >s, R32 = R32
1050                   (ops R32:$dst, R32:$src1, R32:$src2),
1051                   "cmovg {$src2, $dst|$dst, $src2}",
1052                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1053                                    X86_COND_G))]>,
1054                    TB;
1055 def CMOVG32rm : I<0x4F, MRMSrcMem,       // if >s, R32 = [mem32]
1056                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1057                   "cmovg {$src2, $dst|$dst, $src2}",
1058                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1059                                    X86_COND_G))]>,
1060                    TB;
1061
1062 def CMOVS16rr : I<0x48, MRMSrcReg,       // if signed, R16 = R16
1063                   (ops R16:$dst, R16:$src1, R16:$src2),
1064                   "cmovs {$src2, $dst|$dst, $src2}",
1065                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1066                                    X86_COND_S))]>,
1067                   TB, OpSize;
1068 def CMOVS16rm : I<0x48, MRMSrcMem,       // if signed, R16 = [mem16]
1069                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1070                   "cmovs {$src2, $dst|$dst, $src2}",
1071                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1072                                    X86_COND_S))]>,
1073                   TB, OpSize;
1074 def CMOVS32rr : I<0x48, MRMSrcReg,       // if signed, R32 = R32
1075                   (ops R32:$dst, R32:$src1, R32:$src2),
1076                   "cmovs {$src2, $dst|$dst, $src2}",
1077                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1078                                    X86_COND_S))]>,
1079                   TB;
1080 def CMOVS32rm : I<0x48, MRMSrcMem,       // if signed, R32 = [mem32]
1081                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1082                   "cmovs {$src2, $dst|$dst, $src2}",
1083                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1084                                    X86_COND_S))]>,
1085                   TB;
1086
1087 def CMOVNS16rr: I<0x49, MRMSrcReg,       // if !signed, R16 = R16
1088                   (ops R16:$dst, R16:$src1, R16:$src2),
1089                   "cmovns {$src2, $dst|$dst, $src2}",
1090                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1091                                    X86_COND_NS))]>,
1092                   TB, OpSize;
1093 def CMOVNS16rm: I<0x49, MRMSrcMem,       // if !signed, R16 = [mem16]
1094                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1095                   "cmovns {$src2, $dst|$dst, $src2}",
1096                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1097                                    X86_COND_NS))]>,
1098                   TB, OpSize;
1099 def CMOVNS32rr: I<0x49, MRMSrcReg,       // if !signed, R32 = R32
1100                   (ops R32:$dst, R32:$src1, R32:$src2),
1101                   "cmovns {$src2, $dst|$dst, $src2}",
1102                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1103                                    X86_COND_NS))]>,
1104                   TB;
1105 def CMOVNS32rm: I<0x49, MRMSrcMem,       // if !signed, R32 = [mem32]
1106                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1107                   "cmovns {$src2, $dst|$dst, $src2}",
1108                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1109                                    X86_COND_NS))]>,
1110                   TB;
1111
1112 def CMOVP16rr : I<0x4A, MRMSrcReg,       // if parity, R16 = R16
1113                   (ops R16:$dst, R16:$src1, R16:$src2),
1114                   "cmovp {$src2, $dst|$dst, $src2}",
1115                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1116                                    X86_COND_P))]>,
1117                   TB, OpSize;
1118 def CMOVP16rm : I<0x4A, MRMSrcMem,       // if parity, R16 = [mem16]
1119                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1120                   "cmovp {$src2, $dst|$dst, $src2}",
1121                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1122                                    X86_COND_P))]>,
1123                   TB, OpSize;
1124 def CMOVP32rr : I<0x4A, MRMSrcReg,       // if parity, R32 = R32
1125                   (ops R32:$dst, R32:$src1, R32:$src2),
1126                   "cmovp {$src2, $dst|$dst, $src2}",
1127                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1128                                    X86_COND_P))]>,
1129                   TB;
1130 def CMOVP32rm : I<0x4A, MRMSrcMem,       // if parity, R32 = [mem32]
1131                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1132                   "cmovp {$src2, $dst|$dst, $src2}",
1133                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1134                                    X86_COND_P))]>,
1135                   TB;
1136
1137 def CMOVNP16rr : I<0x4B, MRMSrcReg,       // if !parity, R16 = R16
1138                   (ops R16:$dst, R16:$src1, R16:$src2),
1139                   "cmovnp {$src2, $dst|$dst, $src2}",
1140                    [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1141                                     X86_COND_NP))]>,
1142                   TB, OpSize;
1143 def CMOVNP16rm : I<0x4B, MRMSrcMem,       // if !parity, R16 = [mem16]
1144                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1145                   "cmovnp {$src2, $dst|$dst, $src2}",
1146                    [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1147                                     X86_COND_NP))]>,
1148                   TB, OpSize;
1149 def CMOVNP32rr : I<0x4B, MRMSrcReg,       // if !parity, R32 = R32
1150                   (ops R32:$dst, R32:$src1, R32:$src2),
1151                   "cmovnp {$src2, $dst|$dst, $src2}",
1152                    [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1153                                     X86_COND_NP))]>,
1154                   TB;
1155 def CMOVNP32rm : I<0x4B, MRMSrcMem,       // if !parity, R32 = [mem32]
1156                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1157                   "cmovnp {$src2, $dst|$dst, $src2}",
1158                    [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1159                                     X86_COND_NP))]>,
1160                   TB;
1161
1162
1163 // unary instructions
1164 def NEG8r  : I<0xF6, MRM3r, (ops R8 :$dst, R8 :$src), "neg{b} $dst",
1165                [(set R8:$dst, (ineg R8:$src))]>;
1166 def NEG16r : I<0xF7, MRM3r, (ops R16:$dst, R16:$src), "neg{w} $dst",
1167                [(set R16:$dst, (ineg R16:$src))]>, OpSize;
1168 def NEG32r : I<0xF7, MRM3r, (ops R32:$dst, R32:$src), "neg{l} $dst",
1169                [(set R32:$dst, (ineg R32:$src))]>;
1170 let isTwoAddress = 0 in {
1171   def NEG8m  : I<0xF6, MRM3m, (ops i8mem :$dst), "neg{b} $dst",
1172                  [(store (ineg (loadi8 addr:$dst)), addr:$dst)]>;
1173   def NEG16m : I<0xF7, MRM3m, (ops i16mem:$dst), "neg{w} $dst",
1174                  [(store (ineg (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1175   def NEG32m : I<0xF7, MRM3m, (ops i32mem:$dst), "neg{l} $dst",
1176                  [(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
1177
1178 }
1179
1180 def NOT8r  : I<0xF6, MRM2r, (ops R8 :$dst, R8 :$src), "not{b} $dst",
1181                [(set R8:$dst, (not R8:$src))]>;
1182 def NOT16r : I<0xF7, MRM2r, (ops R16:$dst, R16:$src), "not{w} $dst",
1183                [(set R16:$dst, (not R16:$src))]>, OpSize;
1184 def NOT32r : I<0xF7, MRM2r, (ops R32:$dst, R32:$src), "not{l} $dst",
1185                [(set R32:$dst, (not R32:$src))]>;
1186 let isTwoAddress = 0 in {
1187   def NOT8m  : I<0xF6, MRM2m, (ops i8mem :$dst), "not{b} $dst",
1188                  [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
1189   def NOT16m : I<0xF7, MRM2m, (ops i16mem:$dst), "not{w} $dst",
1190                  [(store (not (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1191   def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst",
1192                  [(store (not (loadi32 addr:$dst)), addr:$dst)]>;
1193 }
1194
1195 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
1196 def INC8r  : I<0xFE, MRM0r, (ops R8 :$dst, R8 :$src), "inc{b} $dst",
1197                [(set R8:$dst, (add R8:$src, 1))]>;
1198 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1199 def INC16r : I<0xFF, MRM0r, (ops R16:$dst, R16:$src), "inc{w} $dst",
1200                [(set R16:$dst, (add R16:$src, 1))]>, OpSize;
1201 def INC32r : I<0xFF, MRM0r, (ops R32:$dst, R32:$src), "inc{l} $dst",
1202                [(set R32:$dst, (add R32:$src, 1))]>;
1203 }
1204 let isTwoAddress = 0 in {
1205   def INC8m  : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
1206                [(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
1207   def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
1208                [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
1209   def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
1210                [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
1211 }
1212
1213 def DEC8r  : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst",
1214                [(set R8:$dst, (add R8:$src, -1))]>;
1215 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1216 def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst",
1217                [(set R16:$dst, (add R16:$src, -1))]>, OpSize;
1218 def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst",
1219                [(set R32:$dst, (add R32:$src, -1))]>;
1220 }
1221
1222 let isTwoAddress = 0 in {
1223   def DEC8m  : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
1224                [(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
1225   def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
1226                [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
1227   def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
1228                [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
1229 }
1230
1231 // Logical operators...
1232 let isCommutable = 1 in {   // X = AND Y, Z   --> X = AND Z, Y
1233 def AND8rr   : I<0x20, MRMDestReg,
1234                 (ops R8 :$dst, R8 :$src1, R8 :$src2),
1235                 "and{b} {$src2, $dst|$dst, $src2}",
1236                 [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
1237 def AND16rr  : I<0x21, MRMDestReg,
1238                  (ops R16:$dst, R16:$src1, R16:$src2),
1239                  "and{w} {$src2, $dst|$dst, $src2}",
1240                  [(set R16:$dst, (and R16:$src1, R16:$src2))]>, OpSize;
1241 def AND32rr  : I<0x21, MRMDestReg, 
1242                  (ops R32:$dst, R32:$src1, R32:$src2),
1243                  "and{l} {$src2, $dst|$dst, $src2}",
1244                  [(set R32:$dst, (and R32:$src1, R32:$src2))]>;
1245 }
1246
1247 def AND8rm   : I<0x22, MRMSrcMem, 
1248                  (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1249                  "and{b} {$src2, $dst|$dst, $src2}",
1250                 [(set R8:$dst, (and R8:$src1, (load addr:$src2)))]>;
1251 def AND16rm  : I<0x23, MRMSrcMem, 
1252                  (ops R16:$dst, R16:$src1, i16mem:$src2),
1253                  "and{w} {$src2, $dst|$dst, $src2}",
1254                 [(set R16:$dst, (and R16:$src1, (load addr:$src2)))]>, OpSize;
1255 def AND32rm  : I<0x23, MRMSrcMem,
1256                  (ops R32:$dst, R32:$src1, i32mem:$src2),
1257                  "and{l} {$src2, $dst|$dst, $src2}",
1258                 [(set R32:$dst, (and R32:$src1, (load addr:$src2)))]>;
1259
1260 def AND8ri   : Ii8<0x80, MRM4r, 
1261                    (ops R8 :$dst, R8 :$src1, i8imm :$src2),
1262                    "and{b} {$src2, $dst|$dst, $src2}",
1263                    [(set R8:$dst, (and R8:$src1, imm:$src2))]>;
1264 def AND16ri  : Ii16<0x81, MRM4r, 
1265                     (ops R16:$dst, R16:$src1, i16imm:$src2),
1266                     "and{w} {$src2, $dst|$dst, $src2}",
1267                     [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize;
1268 def AND32ri  : Ii32<0x81, MRM4r, 
1269                     (ops R32:$dst, R32:$src1, i32imm:$src2),
1270                     "and{l} {$src2, $dst|$dst, $src2}",
1271                     [(set R32:$dst, (and R32:$src1, imm:$src2))]>;
1272 def AND16ri8 : Ii8<0x83, MRM4r, 
1273                    (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1274                    "and{w} {$src2, $dst|$dst, $src2}",
1275                    [(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
1276                    OpSize;
1277 def AND32ri8 : Ii8<0x83, MRM4r, 
1278                    (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1279                    "and{l} {$src2, $dst|$dst, $src2}",
1280                    [(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
1281
1282 let isTwoAddress = 0 in {
1283   def AND8mr   : I<0x20, MRMDestMem,
1284                    (ops i8mem :$dst, R8 :$src),
1285                    "and{b} {$src, $dst|$dst, $src}",
1286                    [(store (and (load addr:$dst), R8:$src), addr:$dst)]>;
1287   def AND16mr  : I<0x21, MRMDestMem,
1288                    (ops i16mem:$dst, R16:$src),
1289                    "and{w} {$src, $dst|$dst, $src}",
1290                    [(store (and (load addr:$dst), R16:$src), addr:$dst)]>,
1291                    OpSize;
1292   def AND32mr  : I<0x21, MRMDestMem,
1293                    (ops i32mem:$dst, R32:$src),
1294                    "and{l} {$src, $dst|$dst, $src}",
1295                    [(store (and (load addr:$dst), R32:$src), addr:$dst)]>;
1296   def AND8mi   : Ii8<0x80, MRM4m,
1297                      (ops i8mem :$dst, i8imm :$src),
1298                      "and{b} {$src, $dst|$dst, $src}",
1299                       [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1300   def AND16mi  : Ii16<0x81, MRM4m,
1301                       (ops i16mem:$dst, i16imm:$src),
1302                       "and{w} {$src, $dst|$dst, $src}",
1303                       [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1304                       OpSize;
1305   def AND32mi  : Ii32<0x81, MRM4m,
1306                       (ops i32mem:$dst, i32imm:$src),
1307                       "and{l} {$src, $dst|$dst, $src}",
1308                       [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1309   def AND16mi8 : Ii8<0x83, MRM4m,
1310                      (ops i16mem:$dst, i16i8imm :$src),
1311                      "and{w} {$src, $dst|$dst, $src}",
1312                 [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1313                      OpSize;
1314   def AND32mi8 : Ii8<0x83, MRM4m,
1315                      (ops i32mem:$dst, i32i8imm :$src),
1316                      "and{l} {$src, $dst|$dst, $src}",
1317                 [(store (and (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1318 }
1319
1320
1321 let isCommutable = 1 in {   // X = OR Y, Z   --> X = OR Z, Y
1322 def OR8rr    : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1323                  "or{b} {$src2, $dst|$dst, $src2}",
1324                  [(set R8:$dst, (or R8:$src1, R8:$src2))]>;
1325 def OR16rr   : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1326                  "or{w} {$src2, $dst|$dst, $src2}",
1327                  [(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
1328 def OR32rr   : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1329                  "or{l} {$src2, $dst|$dst, $src2}",
1330                  [(set R32:$dst, (or R32:$src1, R32:$src2))]>;
1331 }
1332 def OR8rm    : I<0x0A, MRMSrcMem , (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1333                  "or{b} {$src2, $dst|$dst, $src2}",
1334                 [(set R8:$dst, (or R8:$src1, (load addr:$src2)))]>;
1335 def OR16rm   : I<0x0B, MRMSrcMem , (ops R16:$dst, R16:$src1, i16mem:$src2),
1336                  "or{w} {$src2, $dst|$dst, $src2}",
1337                 [(set R16:$dst, (or R16:$src1, (load addr:$src2)))]>, OpSize;
1338 def OR32rm   : I<0x0B, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1339                  "or{l} {$src2, $dst|$dst, $src2}",
1340                 [(set R32:$dst, (or R32:$src1, (load addr:$src2)))]>;
1341
1342 def OR8ri    : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1343                     "or{b} {$src2, $dst|$dst, $src2}",
1344                     [(set R8:$dst, (or R8:$src1, imm:$src2))]>;
1345 def OR16ri   : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1346                     "or{w} {$src2, $dst|$dst, $src2}", 
1347                     [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize;
1348 def OR32ri   : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1349                     "or{l} {$src2, $dst|$dst, $src2}",
1350                     [(set R32:$dst, (or R32:$src1, imm:$src2))]>;
1351
1352 def OR16ri8  : Ii8<0x83, MRM1r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1353                    "or{w} {$src2, $dst|$dst, $src2}",
1354                    [(set R16:$dst, (or R16:$src1, i16immSExt8:$src2))]>, OpSize;
1355 def OR32ri8  : Ii8<0x83, MRM1r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1356                    "or{l} {$src2, $dst|$dst, $src2}",
1357                    [(set R32:$dst, (or R32:$src1, i32immSExt8:$src2))]>;
1358 let isTwoAddress = 0 in {
1359   def OR8mr  : I<0x08, MRMDestMem, (ops i8mem:$dst, R8:$src),
1360                  "or{b} {$src, $dst|$dst, $src}",
1361                  [(store (or (load addr:$dst), R8:$src), addr:$dst)]>;
1362   def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, R16:$src),
1363                  "or{w} {$src, $dst|$dst, $src}",
1364                  [(store (or (load addr:$dst), R16:$src), addr:$dst)]>, OpSize;
1365   def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, R32:$src),
1366                  "or{l} {$src, $dst|$dst, $src}",
1367                  [(store (or (load addr:$dst), R32:$src), addr:$dst)]>;
1368   def OR8mi    : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
1369                  "or{b} {$src, $dst|$dst, $src}",
1370                  [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1371   def OR16mi   : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
1372                  "or{w} {$src, $dst|$dst, $src}",
1373                  [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1374                  OpSize;
1375   def OR32mi   : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
1376                  "or{l} {$src, $dst|$dst, $src}",
1377                  [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1378   def OR16mi8  : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
1379                  "or{w} {$src, $dst|$dst, $src}",
1380                  [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1381                      OpSize;
1382   def OR32mi8  : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
1383                  "or{l} {$src, $dst|$dst, $src}",
1384                  [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1385 }
1386
1387
1388 let isCommutable = 1 in {   // X = XOR Y, Z   --> X = XOR Z, Y
1389 def XOR8rr   : I<0x30, MRMDestReg,
1390                  (ops R8 :$dst, R8 :$src1, R8 :$src2),
1391                  "xor{b} {$src2, $dst|$dst, $src2}",
1392                  [(set R8:$dst, (xor R8:$src1, R8:$src2))]>;
1393 def XOR16rr  : I<0x31, MRMDestReg, 
1394                  (ops R16:$dst, R16:$src1, R16:$src2), 
1395                  "xor{w} {$src2, $dst|$dst, $src2}",
1396                  [(set R16:$dst, (xor R16:$src1, R16:$src2))]>, OpSize;
1397 def XOR32rr  : I<0x31, MRMDestReg, 
1398                  (ops R32:$dst, R32:$src1, R32:$src2), 
1399                  "xor{l} {$src2, $dst|$dst, $src2}",
1400                  [(set R32:$dst, (xor R32:$src1, R32:$src2))]>;
1401 }
1402
1403 def XOR8rm   : I<0x32, MRMSrcMem , 
1404                  (ops R8 :$dst, R8:$src1, i8mem :$src2), 
1405                  "xor{b} {$src2, $dst|$dst, $src2}",
1406                  [(set R8:$dst, (xor R8:$src1, (load addr:$src2)))]>;
1407 def XOR16rm  : I<0x33, MRMSrcMem , 
1408                  (ops R16:$dst, R16:$src1, i16mem:$src2), 
1409                  "xor{w} {$src2, $dst|$dst, $src2}",
1410                  [(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
1411 def XOR32rm  : I<0x33, MRMSrcMem , 
1412                  (ops R32:$dst, R32:$src1, i32mem:$src2), 
1413                  "xor{l} {$src2, $dst|$dst, $src2}",
1414                  [(set R32:$dst, (xor R32:$src1, (load addr:$src2)))]>;
1415
1416 def XOR8ri   : Ii8<0x80, MRM6r, 
1417                    (ops R8:$dst, R8:$src1, i8imm:$src2), 
1418                    "xor{b} {$src2, $dst|$dst, $src2}",
1419                    [(set R8:$dst, (xor R8:$src1, imm:$src2))]>;
1420 def XOR16ri  : Ii16<0x81, MRM6r, 
1421                     (ops R16:$dst, R16:$src1, i16imm:$src2), 
1422                     "xor{w} {$src2, $dst|$dst, $src2}",
1423                     [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize;
1424 def XOR32ri  : Ii32<0x81, MRM6r, 
1425                     (ops R32:$dst, R32:$src1, i32imm:$src2), 
1426                     "xor{l} {$src2, $dst|$dst, $src2}",
1427                     [(set R32:$dst, (xor R32:$src1, imm:$src2))]>;
1428 def XOR16ri8 : Ii8<0x83, MRM6r, 
1429                    (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1430                    "xor{w} {$src2, $dst|$dst, $src2}",
1431                    [(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
1432                    OpSize;
1433 def XOR32ri8 : Ii8<0x83, MRM6r, 
1434                    (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1435                    "xor{l} {$src2, $dst|$dst, $src2}",
1436                    [(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
1437 let isTwoAddress = 0 in {
1438   def XOR8mr   : I<0x30, MRMDestMem,
1439                    (ops i8mem :$dst, R8 :$src),
1440                    "xor{b} {$src, $dst|$dst, $src}",
1441                    [(store (xor (load addr:$dst), R8:$src), addr:$dst)]>;
1442   def XOR16mr  : I<0x31, MRMDestMem,
1443                    (ops i16mem:$dst, R16:$src),
1444                    "xor{w} {$src, $dst|$dst, $src}",
1445                    [(store (xor (load addr:$dst), R16:$src), addr:$dst)]>,
1446                    OpSize;
1447   def XOR32mr  : I<0x31, MRMDestMem,
1448                    (ops i32mem:$dst, R32:$src),
1449                    "xor{l} {$src, $dst|$dst, $src}",
1450                    [(store (xor (load addr:$dst), R32:$src), addr:$dst)]>;
1451   def XOR8mi   : Ii8<0x80, MRM6m,
1452                      (ops i8mem :$dst, i8imm :$src),
1453                      "xor{b} {$src, $dst|$dst, $src}",
1454                     [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1455   def XOR16mi  : Ii16<0x81, MRM6m,
1456                       (ops i16mem:$dst, i16imm:$src),
1457                       "xor{w} {$src, $dst|$dst, $src}",
1458                    [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1459                       OpSize;
1460   def XOR32mi  : Ii32<0x81, MRM6m,
1461                       (ops i32mem:$dst, i32imm:$src),
1462                       "xor{l} {$src, $dst|$dst, $src}",
1463                    [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1464   def XOR16mi8 : Ii8<0x83, MRM6m,
1465                      (ops i16mem:$dst, i16i8imm :$src),
1466                      "xor{w} {$src, $dst|$dst, $src}",
1467                  [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1468                      OpSize;
1469   def XOR32mi8 : Ii8<0x83, MRM6m,
1470                      (ops i32mem:$dst, i32i8imm :$src),
1471                      "xor{l} {$src, $dst|$dst, $src}",
1472                  [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1473 }
1474
1475 // Shift instructions
1476 def SHL8rCL  : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
1477                  "shl{b} {%cl, $dst|$dst, %CL}",
1478                  [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
1479 def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
1480                  "shl{w} {%cl, $dst|$dst, %CL}",
1481                  [(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1482 def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
1483                  "shl{l} {%cl, $dst|$dst, %CL}",
1484                  [(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
1485
1486 def SHL8ri   : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1487                    "shl{b} {$src2, $dst|$dst, $src2}",
1488                    [(set R8:$dst, (shl R8:$src1, (i8 imm:$src2)))]>;
1489 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1490 def SHL16ri  : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1491                    "shl{w} {$src2, $dst|$dst, $src2}",
1492                    [(set R16:$dst, (shl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1493 def SHL32ri  : Ii8<0xC1, MRM4r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1494                    "shl{l} {$src2, $dst|$dst, $src2}",
1495                    [(set R32:$dst, (shl R32:$src1, (i8 imm:$src2)))]>;
1496 }
1497
1498 let isTwoAddress = 0 in {
1499   def SHL8mCL  : I<0xD2, MRM4m, (ops i8mem :$dst),
1500                    "shl{b} {%cl, $dst|$dst, %CL}",
1501                    [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
1502                    Imp<[CL],[]>;
1503   def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
1504                    "shl{w} {%cl, $dst|$dst, %CL}",
1505                    [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
1506                    Imp<[CL],[]>, OpSize;
1507   def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
1508                    "shl{l} {%cl, $dst|$dst, %CL}",
1509                    [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
1510                    Imp<[CL],[]>;
1511   def SHL8mi   : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
1512                      "shl{b} {$src, $dst|$dst, $src}",
1513                   [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1514   def SHL16mi  : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
1515                      "shl{w} {$src, $dst|$dst, $src}",
1516                  [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1517                      OpSize;
1518   def SHL32mi  : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
1519                      "shl{l} {$src, $dst|$dst, $src}",
1520                  [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1521 }
1522
1523 def SHR8rCL  : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
1524                  "shr{b} {%cl, $dst|$dst, %CL}",
1525                  [(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
1526 def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
1527                  "shr{w} {%cl, $dst|$dst, %CL}",
1528                  [(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1529 def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
1530                  "shr{l} {%cl, $dst|$dst, %CL}",
1531                  [(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
1532
1533 def SHR8ri   : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1534                    "shr{b} {$src2, $dst|$dst, $src2}",
1535                    [(set R8:$dst, (srl R8:$src1, (i8 imm:$src2)))]>;
1536 def SHR16ri  : Ii8<0xC1, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1537                    "shr{w} {$src2, $dst|$dst, $src2}",
1538                    [(set R16:$dst, (srl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1539 def SHR32ri  : Ii8<0xC1, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1540                    "shr{l} {$src2, $dst|$dst, $src2}",
1541                    [(set R32:$dst, (srl R32:$src1, (i8 imm:$src2)))]>;
1542
1543 let isTwoAddress = 0 in {
1544   def SHR8mCL  : I<0xD2, MRM5m, (ops i8mem :$dst),
1545                    "shr{b} {%cl, $dst|$dst, %CL}",
1546                    [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
1547                    Imp<[CL],[]>;
1548   def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
1549                    "shr{w} {%cl, $dst|$dst, %CL}",
1550                    [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
1551                    Imp<[CL],[]>, OpSize;
1552   def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
1553                    "shr{l} {%cl, $dst|$dst, %CL}",
1554                    [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
1555                    Imp<[CL],[]>;
1556   def SHR8mi   : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
1557                      "shr{b} {$src, $dst|$dst, $src}",
1558                   [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1559   def SHR16mi  : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
1560                      "shr{w} {$src, $dst|$dst, $src}",
1561                  [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1562                      OpSize;
1563   def SHR32mi  : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
1564                      "shr{l} {$src, $dst|$dst, $src}",
1565                  [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1566 }
1567
1568 def SAR8rCL  : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
1569                  "sar{b} {%cl, $dst|$dst, %CL}",
1570                  [(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
1571 def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
1572                  "sar{w} {%cl, $dst|$dst, %CL}",
1573                  [(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1574 def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
1575                  "sar{l} {%cl, $dst|$dst, %CL}",
1576                  [(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
1577
1578 def SAR8ri   : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1579                    "sar{b} {$src2, $dst|$dst, $src2}",
1580                    [(set R8:$dst, (sra R8:$src1, (i8 imm:$src2)))]>;
1581 def SAR16ri  : Ii8<0xC1, MRM7r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1582                    "sar{w} {$src2, $dst|$dst, $src2}",
1583                    [(set R16:$dst, (sra R16:$src1, (i8 imm:$src2)))]>,
1584                    OpSize;
1585 def SAR32ri  : Ii8<0xC1, MRM7r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1586                    "sar{l} {$src2, $dst|$dst, $src2}",
1587                    [(set R32:$dst, (sra R32:$src1, (i8 imm:$src2)))]>;
1588 let isTwoAddress = 0 in {
1589   def SAR8mCL  : I<0xD2, MRM7m, (ops i8mem :$dst),
1590                    "sar{b} {%cl, $dst|$dst, %CL}",
1591                    [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
1592                    Imp<[CL],[]>;
1593   def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
1594                    "sar{w} {%cl, $dst|$dst, %CL}",
1595                    [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
1596                    Imp<[CL],[]>, OpSize;
1597   def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst), 
1598                    "sar{l} {%cl, $dst|$dst, %CL}",
1599                    [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
1600                    Imp<[CL],[]>;
1601   def SAR8mi   : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
1602                      "sar{b} {$src, $dst|$dst, $src}",
1603                   [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1604   def SAR16mi  : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
1605                      "sar{w} {$src, $dst|$dst, $src}",
1606                  [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1607                      OpSize;
1608   def SAR32mi  : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
1609                      "sar{l} {$src, $dst|$dst, $src}",
1610                  [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1611 }
1612
1613 // Rotate instructions
1614 // FIXME: provide shorter instructions when imm8 == 1
1615 def ROL8rCL  : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
1616                  "rol{b} {%cl, $dst|$dst, %CL}",
1617                  [(set R8:$dst, (rotl R8:$src, CL))]>, Imp<[CL],[]>;
1618 def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
1619                  "rol{w} {%cl, $dst|$dst, %CL}",
1620                  [(set R16:$dst, (rotl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1621 def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
1622                  "rol{l} {%cl, $dst|$dst, %CL}",
1623                  [(set R32:$dst, (rotl R32:$src, CL))]>, Imp<[CL],[]>;
1624
1625 def ROL8ri   : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1626                    "rol{b} {$src2, $dst|$dst, $src2}",
1627                    [(set R8:$dst, (rotl R8:$src1, (i8 imm:$src2)))]>;
1628 def ROL16ri  : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1629                    "rol{w} {$src2, $dst|$dst, $src2}",
1630                    [(set R16:$dst, (rotl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1631 def ROL32ri  : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1632                    "rol{l} {$src2, $dst|$dst, $src2}",
1633                    [(set R32:$dst, (rotl R32:$src1, (i8 imm:$src2)))]>;
1634
1635 let isTwoAddress = 0 in {
1636   def ROL8mCL  : I<0xD2, MRM0m, (ops i8mem :$dst),
1637                    "rol{b} {%cl, $dst|$dst, %CL}",
1638                    [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>,
1639                    Imp<[CL],[]>;
1640   def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
1641                    "rol{w} {%cl, $dst|$dst, %CL}",
1642                    [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>,
1643                    Imp<[CL],[]>, OpSize;
1644   def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
1645                    "rol{l} {%cl, $dst|$dst, %CL}",
1646                    [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>,
1647                    Imp<[CL],[]>;
1648   def ROL8mi   : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
1649                      "rol{b} {$src, $dst|$dst, $src}",
1650                  [(store (rotl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1651   def ROL16mi  : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
1652                      "rol{w} {$src, $dst|$dst, $src}",
1653                 [(store (rotl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1654                      OpSize;
1655   def ROL32mi  : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
1656                      "rol{l} {$src, $dst|$dst, $src}",
1657                 [(store (rotl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1658 }
1659
1660 def ROR8rCL  : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
1661                  "ror{b} {%cl, $dst|$dst, %CL}",
1662                  [(set R8:$dst, (rotr R8:$src, CL))]>, Imp<[CL],[]>;
1663 def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
1664                  "ror{w} {%cl, $dst|$dst, %CL}",
1665                  [(set R16:$dst, (rotr R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1666 def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
1667                  "ror{l} {%cl, $dst|$dst, %CL}",
1668                  [(set R32:$dst, (rotr R32:$src, CL))]>, Imp<[CL],[]>;
1669
1670 def ROR8ri   : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1671                    "ror{b} {$src2, $dst|$dst, $src2}",
1672                    [(set R8:$dst, (rotr R8:$src1, (i8 imm:$src2)))]>;
1673 def ROR16ri  : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1674                    "ror{w} {$src2, $dst|$dst, $src2}",
1675                    [(set R16:$dst, (rotr R16:$src1, (i8 imm:$src2)))]>, OpSize;
1676 def ROR32ri  : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1677                    "ror{l} {$src2, $dst|$dst, $src2}",
1678                    [(set R32:$dst, (rotr R32:$src1, (i8 imm:$src2)))]>;
1679 let isTwoAddress = 0 in {
1680   def ROR8mCL  : I<0xD2, MRM1m, (ops i8mem :$dst),
1681                    "ror{b} {%cl, $dst|$dst, %CL}",
1682                    [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>,
1683                    Imp<[CL],[]>;
1684   def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
1685                    "ror{w} {%cl, $dst|$dst, %CL}",
1686                    [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>,
1687                    Imp<[CL],[]>, OpSize;
1688   def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst), 
1689                    "ror{l} {%cl, $dst|$dst, %CL}",
1690                    [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>,
1691                    Imp<[CL],[]>;
1692   def ROR8mi   : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
1693                      "ror{b} {$src, $dst|$dst, $src}",
1694                  [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1695   def ROR16mi  : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
1696                      "ror{w} {$src, $dst|$dst, $src}",
1697                 [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1698                      OpSize;
1699   def ROR32mi  : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
1700                      "ror{l} {$src, $dst|$dst, $src}",
1701                 [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1702 }
1703
1704
1705
1706 // Double shift instructions (generalizations of rotate)
1707
1708 def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1709                    "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1710                    [(set R32:$dst, (X86shld R32:$src1, R32:$src2, CL))]>,
1711                    Imp<[CL],[]>, TB;
1712 def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1713                    "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1714                    [(set R32:$dst, (X86shrd R32:$src1, R32:$src2, CL))]>,
1715                    Imp<[CL],[]>, TB;
1716 def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1717                    "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1718                    [(set R16:$dst, (X86shld R16:$src1, R16:$src2, CL))]>,
1719                    Imp<[CL],[]>, TB, OpSize;
1720 def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1721                    "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1722                    [(set R16:$dst, (X86shrd R16:$src1, R16:$src2, CL))]>,
1723                    Imp<[CL],[]>, TB, OpSize;
1724
1725 let isCommutable = 1 in {  // These instructions commute to each other.
1726 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
1727                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1728                      "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1729                      [(set R32:$dst, (X86shld R32:$src1, R32:$src2,
1730                                       (i8 imm:$src3)))]>,
1731                  TB;
1732 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
1733                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1734                      "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1735                      [(set R32:$dst, (X86shrd R32:$src1, R32:$src2,
1736                                       (i8 imm:$src3)))]>,
1737                  TB;
1738 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
1739                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1740                      "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1741                      [(set R16:$dst, (X86shld R16:$src1, R16:$src2,
1742                                       (i8 imm:$src3)))]>,
1743                      TB, OpSize;
1744 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
1745                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1746                      "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1747                      [(set R16:$dst, (X86shrd R16:$src1, R16:$src2,
1748                                       (i8 imm:$src3)))]>,
1749                      TB, OpSize;
1750 }
1751
1752 let isTwoAddress = 0 in {
1753   def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1754                      "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1755                      [(store (X86shld (loadi32 addr:$dst), R32:$src2, CL),
1756                        addr:$dst)]>,
1757                      Imp<[CL],[]>, TB;
1758   def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1759                     "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1760                     [(store (X86shrd (loadi32 addr:$dst), R32:$src2, CL),
1761                       addr:$dst)]>,
1762                     Imp<[CL],[]>, TB;
1763   def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
1764                       (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1765                       "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1766                       [(store (X86shld (loadi32 addr:$dst), R32:$src2,
1767                                         (i8 imm:$src3)), addr:$dst)]>,
1768                       TB;
1769   def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
1770                        (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1771                        "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1772                        [(store (X86shrd (loadi32 addr:$dst), R32:$src2,
1773                                          (i8 imm:$src3)), addr:$dst)]>,
1774                        TB;
1775
1776   def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1777                      "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1778                      [(store (X86shld (loadi16 addr:$dst), R16:$src2, CL),
1779                        addr:$dst)]>,
1780                      Imp<[CL],[]>, TB, OpSize;
1781   def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1782                     "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1783                     [(store (X86shrd (loadi16 addr:$dst), R16:$src2, CL),
1784                       addr:$dst)]>,
1785                     Imp<[CL],[]>, TB, OpSize;
1786   def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
1787                       (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1788                       "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1789                       [(store (X86shld (loadi16 addr:$dst), R16:$src2,
1790                                         (i8 imm:$src3)), addr:$dst)]>,
1791                       TB, OpSize;
1792   def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
1793                        (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1794                        "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1795                       [(store (X86shrd (loadi16 addr:$dst), R16:$src2,
1796                                         (i8 imm:$src3)), addr:$dst)]>,
1797                        TB, OpSize;
1798 }
1799
1800
1801 // Arithmetic.
1802 let isCommutable = 1 in {   // X = ADD Y, Z   --> X = ADD Z, Y
1803 def ADD8rr   : I<0x00, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1804                  "add{b} {$src2, $dst|$dst, $src2}",
1805                  [(set R8:$dst, (add R8:$src1, R8:$src2))]>;
1806 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1807 def ADD16rr  : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1808                  "add{w} {$src2, $dst|$dst, $src2}",
1809                  [(set R16:$dst, (add R16:$src1, R16:$src2))]>, OpSize;
1810 def ADD32rr  : I<0x01, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1811                  "add{l} {$src2, $dst|$dst, $src2}",
1812                  [(set R32:$dst, (add R32:$src1, R32:$src2))]>;
1813 } // end isConvertibleToThreeAddress
1814 } // end isCommutable
1815 def ADD8rm   : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1816                  "add{b} {$src2, $dst|$dst, $src2}",
1817                  [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>;
1818 def ADD16rm  : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1819                  "add{w} {$src2, $dst|$dst, $src2}",
1820                  [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize;
1821 def ADD32rm  : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1822                  "add{l} {$src2, $dst|$dst, $src2}",
1823                  [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>;
1824
1825 def ADD8ri   : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1826                    "add{b} {$src2, $dst|$dst, $src2}",
1827                    [(set R8:$dst, (add R8:$src1, imm:$src2))]>;
1828
1829 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1830 def ADD16ri  : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1831                     "add{w} {$src2, $dst|$dst, $src2}",
1832                     [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize;
1833 def ADD32ri  : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1834                     "add{l} {$src2, $dst|$dst, $src2}",
1835                     [(set R32:$dst, (add R32:$src1, imm:$src2))]>;
1836 }
1837
1838 // FIXME: move ADD16ri8 above ADD16ri to optimize for space.
1839 def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1840                    "add{w} {$src2, $dst|$dst, $src2}",
1841                    [(set R16:$dst, (add R16:$src1, i16immSExt8:$src2))]>,
1842                    OpSize;
1843 def ADD32ri8 : Ii8<0x83, MRM0r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1844                    "add{l} {$src2, $dst|$dst, $src2}",
1845                    [(set R32:$dst, (add R32:$src1, i32immSExt8:$src2))]>;
1846
1847 let isTwoAddress = 0 in {
1848   def ADD8mr   : I<0x00, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1849                    "add{b} {$src2, $dst|$dst, $src2}",
1850                    [(store (add (load addr:$dst), R8:$src2), addr:$dst)]>;
1851   def ADD16mr  : I<0x01, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1852                    "add{w} {$src2, $dst|$dst, $src2}",
1853                    [(store (add (load addr:$dst), R16:$src2), addr:$dst)]>,
1854                    OpSize;
1855   def ADD32mr  : I<0x01, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1856                    "add{l} {$src2, $dst|$dst, $src2}",
1857                    [(store (add (load addr:$dst), R32:$src2), addr:$dst)]>;
1858   def ADD8mi   : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
1859                      "add{b} {$src2, $dst|$dst, $src2}",
1860                    [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1861   def ADD16mi  : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
1862                       "add{w} {$src2, $dst|$dst, $src2}",
1863                   [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1864                    OpSize;
1865   def ADD32mi  : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
1866                       "add{l} {$src2, $dst|$dst, $src2}",
1867                   [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1868   def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
1869                      "add{w} {$src2, $dst|$dst, $src2}",
1870                 [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1871                    OpSize;
1872   def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
1873                      "add{l} {$src2, $dst|$dst, $src2}",
1874                 [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1875 }
1876
1877 let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
1878 def ADC32rr  : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1879                  "adc{l} {$src2, $dst|$dst, $src2}",
1880                  [(set R32:$dst, (X86adc R32:$src1, R32:$src2))]>;
1881 }
1882 def ADC32rm  : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1883                  "adc{l} {$src2, $dst|$dst, $src2}",
1884                  [(set R32:$dst, (X86adc R32:$src1, (load addr:$src2)))]>;
1885 def ADC32ri  : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1886                     "adc{l} {$src2, $dst|$dst, $src2}",
1887                  [(set R32:$dst, (X86adc R32:$src1, imm:$src2))]>;
1888 def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1889                    "adc{l} {$src2, $dst|$dst, $src2}",
1890                  [(set R32:$dst, (X86adc R32:$src1, i32immSExt8:$src2))]>;
1891
1892 let isTwoAddress = 0 in {
1893   def ADC32mr  : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1894                    "adc{l} {$src2, $dst|$dst, $src2}",
1895                    [(store (X86adc (load addr:$dst), R32:$src2), addr:$dst)]>;
1896   def ADC32mi  : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
1897                       "adc{l} {$src2, $dst|$dst, $src2}",
1898                   [(store (X86adc (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1899   def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
1900                      "adc{l} {$src2, $dst|$dst, $src2}",
1901              [(store (X86adc (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1902 }
1903
1904 def SUB8rr   : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1905                  "sub{b} {$src2, $dst|$dst, $src2}",
1906                  [(set R8:$dst, (sub R8:$src1, R8:$src2))]>;
1907 def SUB16rr  : I<0x29, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1908                  "sub{w} {$src2, $dst|$dst, $src2}",
1909                  [(set R16:$dst, (sub R16:$src1, R16:$src2))]>, OpSize;
1910 def SUB32rr  : I<0x29, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1911                  "sub{l} {$src2, $dst|$dst, $src2}",
1912                  [(set R32:$dst, (sub R32:$src1, R32:$src2))]>;
1913 def SUB8rm   : I<0x2A, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1914                  "sub{b} {$src2, $dst|$dst, $src2}",
1915                  [(set R8:$dst, (sub R8:$src1, (load addr:$src2)))]>;
1916 def SUB16rm  : I<0x2B, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1917                  "sub{w} {$src2, $dst|$dst, $src2}",
1918                  [(set R16:$dst, (sub R16:$src1, (load addr:$src2)))]>, OpSize;
1919 def SUB32rm  : I<0x2B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1920                  "sub{l} {$src2, $dst|$dst, $src2}",
1921                  [(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
1922
1923 def SUB8ri   : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1924                     "sub{b} {$src2, $dst|$dst, $src2}",
1925                     [(set R8:$dst, (sub R8:$src1, imm:$src2))]>;
1926 def SUB16ri  : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1927                     "sub{w} {$src2, $dst|$dst, $src2}",
1928                     [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize;
1929 def SUB32ri  : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1930                     "sub{l} {$src2, $dst|$dst, $src2}",
1931                     [(set R32:$dst, (sub R32:$src1, imm:$src2))]>;
1932 def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1933                    "sub{w} {$src2, $dst|$dst, $src2}",
1934                    [(set R16:$dst, (sub R16:$src1, i16immSExt8:$src2))]>,
1935                    OpSize;
1936 def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1937                    "sub{l} {$src2, $dst|$dst, $src2}",
1938                    [(set R32:$dst, (sub R32:$src1, i32immSExt8:$src2))]>;
1939 let isTwoAddress = 0 in {
1940   def SUB8mr   : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1941                    "sub{b} {$src2, $dst|$dst, $src2}",
1942                    [(store (sub (load addr:$dst), R8:$src2), addr:$dst)]>;
1943   def SUB16mr  : I<0x29, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1944                    "sub{w} {$src2, $dst|$dst, $src2}",
1945                    [(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
1946                    OpSize;
1947   def SUB32mr  : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
1948                    "sub{l} {$src2, $dst|$dst, $src2}",
1949                    [(store (sub (load addr:$dst), R32:$src2), addr:$dst)]>;
1950   def SUB8mi   : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2), 
1951                      "sub{b} {$src2, $dst|$dst, $src2}",
1952                    [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1953   def SUB16mi  : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), 
1954                       "sub{w} {$src2, $dst|$dst, $src2}",
1955                   [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1956                    OpSize;
1957   def SUB32mi  : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), 
1958                       "sub{l} {$src2, $dst|$dst, $src2}",
1959                   [(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1960   def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2), 
1961                      "sub{w} {$src2, $dst|$dst, $src2}",
1962                 [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1963                    OpSize;
1964   def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2), 
1965                      "sub{l} {$src2, $dst|$dst, $src2}",
1966                 [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1967 }
1968
1969 def SBB32rr    : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1970                   "sbb{l} {$src2, $dst|$dst, $src2}",
1971                   [(set R32:$dst, (X86sbb R32:$src1, R32:$src2))]>;
1972
1973 let isTwoAddress = 0 in {
1974   def SBB32mr  : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
1975                    "sbb{l} {$src2, $dst|$dst, $src2}",
1976                    [(store (X86sbb (load addr:$dst), R32:$src2), addr:$dst)]>;
1977   def SBB8mi  : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), 
1978                       "sbb{b} {$src2, $dst|$dst, $src2}",
1979                    [(store (X86sbb (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1980   def SBB16mi  : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), 
1981                       "sbb{w} {$src2, $dst|$dst, $src2}",
1982                   [(store (X86sbb (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1983                      OpSize;
1984   def SBB32mi  : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), 
1985                       "sbb{l} {$src2, $dst|$dst, $src2}",
1986                   [(store (X86sbb (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1987   def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i16i8imm :$src2), 
1988                      "sbb{w} {$src2, $dst|$dst, $src2}",
1989              [(store (X86sbb (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1990                      OpSize;
1991   def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2), 
1992                      "sbb{l} {$src2, $dst|$dst, $src2}",
1993              [(store (X86sbb (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1994 }
1995 def SBB8ri   : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1996                     "sbb{b} {$src2, $dst|$dst, $src2}",
1997                     [(set R8:$dst, (X86sbb R8:$src1, imm:$src2))]>;
1998 def SBB16ri  : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1999                     "sbb{w} {$src2, $dst|$dst, $src2}",
2000                     [(set R16:$dst, (X86sbb R16:$src1, imm:$src2))]>, OpSize;
2001
2002 def SBB32rm  : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
2003                     "sbb{l} {$src2, $dst|$dst, $src2}",
2004                     [(set R32:$dst, (X86sbb R32:$src1, (load addr:$src2)))]>;
2005 def SBB32ri  : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
2006                     "sbb{l} {$src2, $dst|$dst, $src2}",
2007                     [(set R32:$dst, (X86sbb R32:$src1, imm:$src2))]>;
2008
2009 def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
2010                    "sbb{w} {$src2, $dst|$dst, $src2}",
2011                    [(set R16:$dst, (X86sbb R16:$src1, i16immSExt8:$src2))]>,
2012                    OpSize;
2013 def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
2014                    "sbb{l} {$src2, $dst|$dst, $src2}",
2015                    [(set R32:$dst, (X86sbb R32:$src1, i32immSExt8:$src2))]>;
2016
2017 let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
2018 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
2019                  "imul{w} {$src2, $dst|$dst, $src2}",
2020                  [(set R16:$dst, (mul R16:$src1, R16:$src2))]>, TB, OpSize;
2021 def IMUL32rr : I<0xAF, MRMSrcReg, (ops R32:$dst, R32:$src1, R32:$src2),
2022                  "imul{l} {$src2, $dst|$dst, $src2}",
2023                  [(set R32:$dst, (mul R32:$src1, R32:$src2))]>, TB;
2024 }
2025 def IMUL16rm : I<0xAF, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
2026                  "imul{w} {$src2, $dst|$dst, $src2}",
2027                  [(set R16:$dst, (mul R16:$src1, (load addr:$src2)))]>,
2028                  TB, OpSize;
2029 def IMUL32rm : I<0xAF, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
2030                  "imul{l} {$src2, $dst|$dst, $src2}",
2031                  [(set R32:$dst, (mul R32:$src1, (load addr:$src2)))]>, TB;
2032
2033 } // end Two Address instructions
2034
2035 // Suprisingly enough, these are not two address instructions!
2036 def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // R16 = R16*I16
2037                       (ops R16:$dst, R16:$src1, i16imm:$src2),
2038                       "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2039                       [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize;
2040 def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // R32 = R32*I32
2041                       (ops R32:$dst, R32:$src1, i32imm:$src2),
2042                       "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2043                       [(set R32:$dst, (mul R32:$src1, imm:$src2))]>;
2044 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // R16 = R16*I8
2045                      (ops R16:$dst, R16:$src1, i16i8imm:$src2),
2046                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2047                      [(set R16:$dst, (mul R16:$src1, i16immSExt8:$src2))]>,
2048                      OpSize;
2049 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // R32 = R32*I8
2050                      (ops R32:$dst, R32:$src1, i32i8imm:$src2),
2051                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2052                      [(set R32:$dst, (mul R32:$src1, i32immSExt8:$src2))]>;
2053
2054 def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                      // R16 = [mem16]*I16
2055                       (ops R16:$dst, i16mem:$src1, i16imm:$src2),
2056                       "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2057                       [(set R16:$dst, (mul (load addr:$src1), imm:$src2))]>,
2058                       OpSize;
2059 def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                      // R32 = [mem32]*I32
2060                       (ops R32:$dst, i32mem:$src1, i32imm:$src2),
2061                       "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2062                       [(set R32:$dst, (mul (load addr:$src1), imm:$src2))]>;
2063 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // R16 = [mem16]*I8
2064                      (ops R16:$dst, i16mem:$src1, i16i8imm :$src2),
2065                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2066                   [(set R16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
2067                      OpSize;
2068 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // R32 = [mem32]*I8
2069                      (ops R32:$dst, i32mem:$src1, i32i8imm: $src2),
2070                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2071                   [(set R32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
2072
2073 //===----------------------------------------------------------------------===//
2074 // Test instructions are just like AND, except they don't generate a result.
2075 //
2076 let isCommutable = 1 in {   // TEST X, Y   --> TEST Y, X
2077 def TEST8rr  : I<0x84, MRMDestReg, (ops R8:$src1, R8:$src2),
2078                  "test{b} {$src2, $src1|$src1, $src2}",
2079                  [(X86test R8:$src1, R8:$src2)]>;
2080 def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
2081                  "test{w} {$src2, $src1|$src1, $src2}",
2082                  [(X86test R16:$src1, R16:$src2)]>, OpSize;
2083 def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
2084                  "test{l} {$src2, $src1|$src1, $src2}",
2085                  [(X86test R32:$src1, R32:$src2)]>;
2086 }
2087 def TEST8mr  : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
2088                  "test{b} {$src2, $src1|$src1, $src2}",
2089                  [(X86test (loadi8 addr:$src1), R8:$src2)]>;
2090 def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
2091                  "test{w} {$src2, $src1|$src1, $src2}",
2092                  [(X86test (loadi16 addr:$src1), R16:$src2)]>,
2093                OpSize;
2094 def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
2095                  "test{l} {$src2, $src1|$src1, $src2}",
2096                  [(X86test (loadi32 addr:$src1), R32:$src2)]>;
2097 def TEST8rm  : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
2098                  "test{b} {$src2, $src1|$src1, $src2}",
2099                  [(X86test R8:$src1, (loadi8 addr:$src2))]>;
2100 def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
2101                  "test{w} {$src2, $src1|$src1, $src2}",
2102                  [(X86test R16:$src1, (loadi16 addr:$src2))]>,
2103                OpSize;
2104 def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
2105                  "test{l} {$src2, $src1|$src1, $src2}",
2106                  [(X86test R32:$src1, (loadi32 addr:$src2))]>;
2107
2108 def TEST8ri  : Ii8 <0xF6, MRM0r,                     // flags = R8  & imm8
2109                     (ops R8:$src1, i8imm:$src2),
2110                     "test{b} {$src2, $src1|$src1, $src2}",
2111                     [(X86test R8:$src1, imm:$src2)]>;
2112 def TEST16ri : Ii16<0xF7, MRM0r,                     // flags = R16 & imm16
2113                     (ops R16:$src1, i16imm:$src2),
2114                     "test{w} {$src2, $src1|$src1, $src2}",
2115                     [(X86test R16:$src1, imm:$src2)]>, OpSize;
2116 def TEST32ri : Ii32<0xF7, MRM0r,                     // flags = R32 & imm32
2117                     (ops R32:$src1, i32imm:$src2),
2118                     "test{l} {$src2, $src1|$src1, $src2}",
2119                     [(X86test R32:$src1, imm:$src2)]>;
2120 def TEST8mi  : Ii8 <0xF6, MRM0m,                     // flags = [mem8]  & imm8
2121                     (ops i8mem:$src1, i8imm:$src2),
2122                     "test{b} {$src2, $src1|$src1, $src2}",
2123                     [(X86test (loadi8 addr:$src1), imm:$src2)]>;
2124 def TEST16mi : Ii16<0xF7, MRM0m,                     // flags = [mem16] & imm16
2125                     (ops i16mem:$src1, i16imm:$src2),
2126                     "test{w} {$src2, $src1|$src1, $src2}",
2127                     [(X86test (loadi16 addr:$src1), imm:$src2)]>,
2128                OpSize;
2129 def TEST32mi : Ii32<0xF7, MRM0m,                     // flags = [mem32] & imm32
2130                     (ops i32mem:$src1, i32imm:$src2),
2131                     "test{l} {$src2, $src1|$src1, $src2}",
2132                     [(X86test (loadi32 addr:$src1), imm:$src2)]>;
2133
2134
2135 // Condition code ops, incl. set if equal/not equal/...
2136 def SAHF     : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>;  // flags = AH
2137 def LAHF     : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>;  // AH = flags
2138
2139 def SETEr    : I<0x94, MRM0r, 
2140                  (ops R8   :$dst),
2141                  "sete $dst",
2142                  [(set R8:$dst, (X86setcc X86_COND_E))]>,
2143                TB;                        // R8 = ==
2144 def SETEm    : I<0x94, MRM0m, 
2145                  (ops i8mem:$dst),
2146                  "sete $dst",
2147                  [(store (X86setcc X86_COND_E), addr:$dst)]>,
2148                TB;                        // [mem8] = ==
2149 def SETNEr   : I<0x95, MRM0r, 
2150                  (ops R8   :$dst),
2151                  "setne $dst",
2152                  [(set R8:$dst, (X86setcc X86_COND_NE))]>,
2153                TB;                        // R8 = !=
2154 def SETNEm   : I<0x95, MRM0m, 
2155                  (ops i8mem:$dst),
2156                  "setne $dst",
2157                  [(store (X86setcc X86_COND_NE), addr:$dst)]>,
2158                TB;                        // [mem8] = !=
2159 def SETLr    : I<0x9C, MRM0r, 
2160                  (ops R8   :$dst),
2161                  "setl $dst",
2162                  [(set R8:$dst, (X86setcc X86_COND_L))]>,
2163                TB;                        // R8 = <  signed
2164 def SETLm    : I<0x9C, MRM0m, 
2165                  (ops i8mem:$dst),
2166                  "setl $dst",
2167                  [(store (X86setcc X86_COND_L), addr:$dst)]>,
2168                TB;                        // [mem8] = <  signed
2169 def SETGEr   : I<0x9D, MRM0r, 
2170                  (ops R8   :$dst),
2171                  "setge $dst",
2172                  [(set R8:$dst, (X86setcc X86_COND_GE))]>,
2173                TB;                        // R8 = >= signed
2174 def SETGEm   : I<0x9D, MRM0m, 
2175                  (ops i8mem:$dst),
2176                  "setge $dst",
2177                  [(store (X86setcc X86_COND_GE), addr:$dst)]>,
2178                TB;                        // [mem8] = >= signed
2179 def SETLEr   : I<0x9E, MRM0r, 
2180                  (ops R8   :$dst),
2181                  "setle $dst",
2182                  [(set R8:$dst, (X86setcc X86_COND_LE))]>,
2183                TB;                        // R8 = <= signed
2184 def SETLEm   : I<0x9E, MRM0m, 
2185                  (ops i8mem:$dst),
2186                  "setle $dst",
2187                  [(store (X86setcc X86_COND_LE), addr:$dst)]>,
2188                TB;                        // [mem8] = <= signed
2189 def SETGr    : I<0x9F, MRM0r, 
2190                  (ops R8   :$dst),
2191                  "setg $dst",
2192                  [(set R8:$dst, (X86setcc X86_COND_G))]>,
2193                TB;                        // R8 = >  signed
2194 def SETGm    : I<0x9F, MRM0m, 
2195                  (ops i8mem:$dst),
2196                  "setg $dst",
2197                  [(store (X86setcc X86_COND_G), addr:$dst)]>,
2198                TB;                        // [mem8] = >  signed
2199
2200 def SETBr    : I<0x92, MRM0r,
2201                  (ops R8   :$dst),
2202                  "setb $dst",
2203                  [(set R8:$dst, (X86setcc X86_COND_B))]>,
2204                TB;                        // R8 = <  unsign
2205 def SETBm    : I<0x92, MRM0m,
2206                  (ops i8mem:$dst),
2207                  "setb $dst",
2208                  [(store (X86setcc X86_COND_B), addr:$dst)]>,
2209                TB;                        // [mem8] = <  unsign
2210 def SETAEr   : I<0x93, MRM0r, 
2211                  (ops R8   :$dst),
2212                  "setae $dst",
2213                  [(set R8:$dst, (X86setcc X86_COND_AE))]>,
2214                TB;                        // R8 = >= unsign
2215 def SETAEm   : I<0x93, MRM0m, 
2216                  (ops i8mem:$dst),
2217                  "setae $dst",
2218                  [(store (X86setcc X86_COND_AE), addr:$dst)]>,
2219                TB;                        // [mem8] = >= unsign
2220 def SETBEr   : I<0x96, MRM0r, 
2221                  (ops R8   :$dst),
2222                  "setbe $dst",
2223                  [(set R8:$dst, (X86setcc X86_COND_BE))]>,
2224                TB;                        // R8 = <= unsign
2225 def SETBEm   : I<0x96, MRM0m, 
2226                  (ops i8mem:$dst),
2227                  "setbe $dst",
2228                  [(store (X86setcc X86_COND_BE), addr:$dst)]>,
2229                TB;                        // [mem8] = <= unsign
2230 def SETAr    : I<0x97, MRM0r, 
2231                  (ops R8   :$dst),
2232                  "seta $dst",
2233                  [(set R8:$dst, (X86setcc X86_COND_A))]>,
2234                TB;                        // R8 = >  signed
2235 def SETAm    : I<0x97, MRM0m, 
2236                  (ops i8mem:$dst),
2237                  "seta $dst",
2238                  [(store (X86setcc X86_COND_A), addr:$dst)]>,
2239                TB;                        // [mem8] = >  signed
2240
2241 def SETSr    : I<0x98, MRM0r, 
2242                  (ops R8   :$dst),
2243                  "sets $dst",
2244                  [(set R8:$dst, (X86setcc X86_COND_S))]>,
2245                TB;                        // R8 = <sign bit>
2246 def SETSm    : I<0x98, MRM0m, 
2247                  (ops i8mem:$dst),
2248                  "sets $dst",
2249                  [(store (X86setcc X86_COND_S), addr:$dst)]>,
2250                TB;                        // [mem8] = <sign bit>
2251 def SETNSr   : I<0x99, MRM0r, 
2252                  (ops R8   :$dst),
2253                  "setns $dst",
2254                  [(set R8:$dst, (X86setcc X86_COND_NS))]>,
2255                TB;                        // R8 = !<sign bit>
2256 def SETNSm   : I<0x99, MRM0m, 
2257                  (ops i8mem:$dst),
2258                  "setns $dst",
2259                  [(store (X86setcc X86_COND_NS), addr:$dst)]>,
2260                TB;                        // [mem8] = !<sign bit>
2261 def SETPr    : I<0x9A, MRM0r, 
2262                  (ops R8   :$dst),
2263                  "setp $dst",
2264                  [(set R8:$dst, (X86setcc X86_COND_P))]>,
2265                TB;                        // R8 = parity
2266 def SETPm    : I<0x9A, MRM0m, 
2267                  (ops i8mem:$dst),
2268                  "setp $dst",
2269                  [(store (X86setcc X86_COND_P), addr:$dst)]>,
2270                TB;                        // [mem8] = parity
2271 def SETNPr   : I<0x9B, MRM0r, 
2272                  (ops R8   :$dst),
2273                  "setnp $dst",
2274                  [(set R8:$dst, (X86setcc X86_COND_NP))]>,
2275                TB;                        // R8 = not parity
2276 def SETNPm   : I<0x9B, MRM0m, 
2277                  (ops i8mem:$dst),
2278                  "setnp $dst",
2279                  [(store (X86setcc X86_COND_NP), addr:$dst)]>,
2280                TB;                        // [mem8] = not parity
2281
2282 // Integer comparisons
2283 def CMP8rr  : I<0x38, MRMDestReg,
2284                 (ops R8 :$src1, R8 :$src2),
2285                 "cmp{b} {$src2, $src1|$src1, $src2}",
2286                 [(X86cmp R8:$src1, R8:$src2)]>;
2287 def CMP16rr : I<0x39, MRMDestReg,
2288                 (ops R16:$src1, R16:$src2),
2289                 "cmp{w} {$src2, $src1|$src1, $src2}",
2290                 [(X86cmp R16:$src1, R16:$src2)]>, OpSize;
2291 def CMP32rr : I<0x39, MRMDestReg,
2292                 (ops R32:$src1, R32:$src2),
2293                 "cmp{l} {$src2, $src1|$src1, $src2}",
2294                 [(X86cmp R32:$src1, R32:$src2)]>;
2295 def CMP8mr  : I<0x38, MRMDestMem,
2296                 (ops i8mem :$src1, R8 :$src2),
2297                 "cmp{b} {$src2, $src1|$src1, $src2}",
2298                 [(X86cmp (loadi8 addr:$src1), R8:$src2)]>;
2299 def CMP16mr : I<0x39, MRMDestMem,
2300                 (ops i16mem:$src1, R16:$src2),
2301                 "cmp{w} {$src2, $src1|$src1, $src2}",
2302                 [(X86cmp (loadi16 addr:$src1), R16:$src2)]>, OpSize;
2303 def CMP32mr : I<0x39, MRMDestMem,
2304                 (ops i32mem:$src1, R32:$src2),
2305                 "cmp{l} {$src2, $src1|$src1, $src2}",
2306                 [(X86cmp (loadi32 addr:$src1), R32:$src2)]>;
2307 def CMP8rm  : I<0x3A, MRMSrcMem,
2308                 (ops R8 :$src1, i8mem :$src2),
2309                 "cmp{b} {$src2, $src1|$src1, $src2}",
2310                 [(X86cmp R8:$src1, (loadi8 addr:$src2))]>;
2311 def CMP16rm : I<0x3B, MRMSrcMem,
2312                 (ops R16:$src1, i16mem:$src2),
2313                 "cmp{w} {$src2, $src1|$src1, $src2}",
2314                 [(X86cmp R16:$src1, (loadi16 addr:$src2))]>, OpSize;
2315 def CMP32rm : I<0x3B, MRMSrcMem,
2316                 (ops R32:$src1, i32mem:$src2),
2317                 "cmp{l} {$src2, $src1|$src1, $src2}",
2318                 [(X86cmp R32:$src1, (loadi32 addr:$src2))]>;
2319 def CMP8ri  : Ii8<0x80, MRM7r,
2320                   (ops R8:$src1, i8imm:$src2),
2321                   "cmp{b} {$src2, $src1|$src1, $src2}",
2322                   [(X86cmp R8:$src1, imm:$src2)]>;
2323 def CMP16ri : Ii16<0x81, MRM7r,
2324                    (ops R16:$src1, i16imm:$src2),
2325                    "cmp{w} {$src2, $src1|$src1, $src2}",
2326                    [(X86cmp R16:$src1, imm:$src2)]>, OpSize;
2327 def CMP32ri : Ii32<0x81, MRM7r,
2328                    (ops R32:$src1, i32imm:$src2),
2329                    "cmp{l} {$src2, $src1|$src1, $src2}",
2330                    [(X86cmp R32:$src1, imm:$src2)]>;
2331 def CMP8mi  : Ii8 <0x80, MRM7m,
2332                    (ops i8mem :$src1, i8imm :$src2),
2333                    "cmp{b} {$src2, $src1|$src1, $src2}",
2334                    [(X86cmp (loadi8 addr:$src1), imm:$src2)]>;
2335 def CMP16mi : Ii16<0x81, MRM7m,
2336                    (ops i16mem:$src1, i16imm:$src2),
2337                    "cmp{w} {$src2, $src1|$src1, $src2}",
2338                    [(X86cmp (loadi16 addr:$src1), imm:$src2)]>, OpSize;
2339 def CMP32mi : Ii32<0x81, MRM7m,
2340                    (ops i32mem:$src1, i32imm:$src2),
2341                    "cmp{l} {$src2, $src1|$src1, $src2}",
2342                    [(X86cmp (loadi32 addr:$src1), imm:$src2)]>;
2343
2344 // Sign/Zero extenders
2345 def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
2346                    "movs{bw|x} {$src, $dst|$dst, $src}",
2347                    [(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
2348 def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2349                    "movs{bw|x} {$src, $dst|$dst, $src}",
2350                    [(set R16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
2351 def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
2352                    "movs{bl|x} {$src, $dst|$dst, $src}",
2353                    [(set R32:$dst, (sext R8:$src))]>, TB;
2354 def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2355                    "movs{bl|x} {$src, $dst|$dst, $src}",
2356                    [(set R32:$dst, (sextloadi32i8 addr:$src))]>, TB;
2357 def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
2358                    "movs{wl|x} {$src, $dst|$dst, $src}",
2359                    [(set R32:$dst, (sext R16:$src))]>, TB;
2360 def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2361                    "movs{wl|x} {$src, $dst|$dst, $src}",
2362                    [(set R32:$dst, (sextloadi32i16 addr:$src))]>, TB;
2363
2364 def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
2365                    "movz{bw|x} {$src, $dst|$dst, $src}",
2366                    [(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
2367 def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2368                    "movz{bw|x} {$src, $dst|$dst, $src}",
2369                    [(set R16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
2370 def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
2371                    "movz{bl|x} {$src, $dst|$dst, $src}",
2372                    [(set R32:$dst, (zext R8:$src))]>, TB;
2373 def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2374                    "movz{bl|x} {$src, $dst|$dst, $src}",
2375                    [(set R32:$dst, (zextloadi32i8 addr:$src))]>, TB;
2376 def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
2377                    "movz{wl|x} {$src, $dst|$dst, $src}",
2378                    [(set R32:$dst, (zext R16:$src))]>, TB;
2379 def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2380                    "movz{wl|x} {$src, $dst|$dst, $src}",
2381                    [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB;
2382
2383 //===----------------------------------------------------------------------===//
2384 // XMM Floating point support (requires SSE / SSE2)
2385 //===----------------------------------------------------------------------===//
2386
2387 def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2388                 "movss {$src, $dst|$dst, $src}", []>,
2389               Requires<[HasSSE1]>, XS;
2390 def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2391                 "movsd {$src, $dst|$dst, $src}", []>,
2392               Requires<[HasSSE2]>, XD;
2393
2394 def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2395                 "movss {$src, $dst|$dst, $src}",
2396                 [(set FR32:$dst, (loadf32 addr:$src))]>,
2397               Requires<[HasSSE1]>, XS;
2398 def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
2399                 "movss {$src, $dst|$dst, $src}",
2400                 [(store FR32:$src, addr:$dst)]>,
2401               Requires<[HasSSE1]>, XS;
2402 def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2403                 "movsd {$src, $dst|$dst, $src}",
2404                 [(set FR64:$dst, (loadf64 addr:$src))]>,
2405               Requires<[HasSSE2]>, XD;
2406 def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
2407                 "movsd {$src, $dst|$dst, $src}",
2408                 [(store FR64:$src, addr:$dst)]>,
2409               Requires<[HasSSE2]>, XD;
2410
2411 def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
2412                    "cvttss2si {$src, $dst|$dst, $src}",
2413                    [(set R32:$dst, (fp_to_sint FR32:$src))]>,
2414                  Requires<[HasSSE1]>, XS;
2415 def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
2416                    "cvttss2si {$src, $dst|$dst, $src}",
2417                    [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
2418                  Requires<[HasSSE1]>, XS;
2419 def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
2420                    "cvttsd2si {$src, $dst|$dst, $src}",
2421                    [(set R32:$dst, (fp_to_sint FR64:$src))]>,
2422                  Requires<[HasSSE2]>, XD;
2423 def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
2424                    "cvttsd2si {$src, $dst|$dst, $src}",
2425                    [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
2426                  Requires<[HasSSE2]>, XD;
2427 def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
2428                   "cvtss2sd {$src, $dst|$dst, $src}",
2429                   [(set FR64:$dst, (fextend FR32:$src))]>,
2430                 Requires<[HasSSE2]>, XD;
2431 def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
2432                   "cvtss2sd {$src, $dst|$dst, $src}",
2433                   [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
2434                 Requires<[HasSSE2]>, XD;
2435 def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
2436                   "cvtsd2ss {$src, $dst|$dst, $src}",
2437                   [(set FR32:$dst, (fround FR64:$src))]>,
2438                 Requires<[HasSSE2]>, XS;
2439 def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), 
2440                   "cvtsd2ss {$src, $dst|$dst, $src}",
2441                   [(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
2442                 Requires<[HasSSE2]>, XS;
2443 def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
2444                   "cvtsi2ss {$src, $dst|$dst, $src}",
2445                   [(set FR32:$dst, (sint_to_fp R32:$src))]>,
2446                 Requires<[HasSSE2]>, XS;
2447 def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
2448                   "cvtsi2ss {$src, $dst|$dst, $src}",
2449                   [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2450                 Requires<[HasSSE2]>, XS;
2451 def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
2452                   "cvtsi2sd {$src, $dst|$dst, $src}",
2453                   [(set FR64:$dst, (sint_to_fp R32:$src))]>,
2454                 Requires<[HasSSE2]>, XD;
2455 def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
2456                   "cvtsi2sd {$src, $dst|$dst, $src}",
2457                   [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2458                 Requires<[HasSSE2]>, XD;
2459
2460 def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2461                  "sqrtss {$src, $dst|$dst, $src}",
2462                  [(set FR32:$dst, (fsqrt FR32:$src))]>,
2463                Requires<[HasSSE1]>, XS;
2464 def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2465                  "sqrtss {$src, $dst|$dst, $src}",
2466                  [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>,
2467                Requires<[HasSSE1]>, XS;
2468 def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2469                  "sqrtsd {$src, $dst|$dst, $src}",
2470                  [(set FR64:$dst, (fsqrt FR64:$src))]>,
2471                Requires<[HasSSE2]>, XD;
2472 def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2473                  "sqrtsd {$src, $dst|$dst, $src}",
2474                  [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>,
2475                Requires<[HasSSE2]>, XD;
2476
2477 def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2),
2478                  "ucomiss {$src2, $src1|$src1, $src2}",
2479                  [(X86cmp FR32:$src1, FR32:$src2)]>,
2480                Requires<[HasSSE1]>, TB;
2481 def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2),
2482                  "ucomiss {$src2, $src1|$src1, $src2}",
2483                  [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>,
2484                Requires<[HasSSE1]>, TB;
2485 def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2),
2486                  "ucomisd {$src2, $src1|$src1, $src2}",
2487                  [(X86cmp FR64:$src1, FR64:$src2)]>,
2488                Requires<[HasSSE2]>, TB, OpSize;
2489 def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2),
2490                  "ucomisd {$src2, $src1|$src1, $src2}",
2491                  [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>,
2492                Requires<[HasSSE2]>, TB, OpSize;
2493
2494 // Pseudo-instructions that map fld0 to xorps/xorpd for sse.
2495 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
2496 def FLD0SS : I<0x57, MRMInitReg, (ops FR32:$dst),
2497                "xorps $dst, $dst", [(set FR32:$dst, fp32imm0)]>,
2498              Requires<[HasSSE1]>, TB;
2499 def FLD0SD : I<0x57, MRMInitReg, (ops FR64:$dst),
2500                "xorpd $dst, $dst", [(set FR64:$dst, fp64imm0)]>,
2501              Requires<[HasSSE2]>, TB, OpSize;
2502
2503 let isTwoAddress = 1 in {
2504 // SSE Scalar Arithmetic
2505 let isCommutable = 1 in {
2506 def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2507                 "addss {$src2, $dst|$dst, $src2}",
2508                 [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>,
2509               Requires<[HasSSE1]>, XS;
2510 def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2511                 "addsd {$src2, $dst|$dst, $src2}",
2512                 [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>,
2513               Requires<[HasSSE2]>, XD;
2514 def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2515                 "mulss {$src2, $dst|$dst, $src2}",
2516                 [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>,
2517               Requires<[HasSSE1]>, XS;
2518 def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2519                 "mulsd {$src2, $dst|$dst, $src2}",
2520                 [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>,
2521               Requires<[HasSSE2]>, XD;
2522 }
2523
2524 def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2525                 "addss {$src2, $dst|$dst, $src2}",
2526                 [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>,
2527               Requires<[HasSSE1]>, XS;
2528 def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2529                 "addsd {$src2, $dst|$dst, $src2}",
2530                 [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>,
2531               Requires<[HasSSE2]>, XD;
2532 def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2533                 "mulss {$src2, $dst|$dst, $src2}",
2534                 [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>,
2535               Requires<[HasSSE1]>, XS;
2536 def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2537                 "mulsd {$src2, $dst|$dst, $src2}",
2538                 [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>,
2539               Requires<[HasSSE2]>, XD;
2540
2541 def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2542                 "divss {$src2, $dst|$dst, $src2}",
2543                 [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>,
2544               Requires<[HasSSE1]>, XS;
2545 def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2546                 "divss {$src2, $dst|$dst, $src2}",
2547                 [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>,
2548               Requires<[HasSSE1]>, XS;
2549 def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2550                 "divsd {$src2, $dst|$dst, $src2}",
2551                 [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>,
2552               Requires<[HasSSE2]>, XD;
2553 def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2554                 "divsd {$src2, $dst|$dst, $src2}",
2555                 [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>,
2556               Requires<[HasSSE2]>, XD;
2557
2558 def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2559                 "subss {$src2, $dst|$dst, $src2}",
2560                 [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>,
2561               Requires<[HasSSE1]>, XS;
2562 def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2563                 "subss {$src2, $dst|$dst, $src2}",
2564                 [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>,
2565               Requires<[HasSSE1]>, XS;
2566 def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2567                 "subsd {$src2, $dst|$dst, $src2}",
2568                 [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>,
2569               Requires<[HasSSE2]>, XD;
2570 def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2571                 "subsd {$src2, $dst|$dst, $src2}",
2572                 [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>,
2573               Requires<[HasSSE2]>, XD;
2574
2575 // SSE compare
2576 def CMPSSrr : I<0xC2, MRMSrcReg, 
2577                 (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
2578                 "cmp${cc}ss {$src, $dst|$dst, $src}", []>,
2579               Requires<[HasSSE1]>, XS;
2580 def CMPSSrm : I<0xC2, MRMSrcMem, 
2581                 (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
2582                 "cmp${cc}ss {$src, $dst|$dst, $src}", []>,
2583               Requires<[HasSSE1]>, XS;
2584 def CMPSDrr : I<0xC2, MRMSrcReg, 
2585                 (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
2586                 "cmp${cc}sd {$src, $dst|$dst, $src}", []>,
2587               Requires<[HasSSE1]>, XD;
2588 def CMPSDrm : I<0xC2, MRMSrcMem, 
2589                 (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
2590                 "cmp${cc}sd {$src, $dst|$dst, $src}", []>,
2591               Requires<[HasSSE2]>, XD;
2592
2593 // SSE Logical - these all operate on packed values
2594 let isCommutable = 1 in {
2595 def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2596                 "andps {$src2, $dst|$dst, $src2}",
2597                 [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>,
2598               Requires<[HasSSE1]>, TB;
2599 def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2600                 "andpd {$src2, $dst|$dst, $src2}",
2601                 [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>,
2602               Requires<[HasSSE2]>, TB, OpSize;
2603 def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2604                 "orps {$src2, $dst|$dst, $src2}", []>,
2605              Requires<[HasSSE1]>, TB;
2606 def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2607                 "orpd {$src2, $dst|$dst, $src2}", []>,
2608              Requires<[HasSSE2]>, TB, OpSize;
2609 def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2610                 "xorps {$src2, $dst|$dst, $src2}",
2611                 [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>,
2612               Requires<[HasSSE1]>, TB;
2613 def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2614                 "xorpd {$src2, $dst|$dst, $src2}",
2615                 [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>,
2616               Requires<[HasSSE2]>, TB, OpSize;
2617 }
2618 def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
2619                 "andps {$src2, $dst|$dst, $src2}",
2620                 [(set FR32:$dst, (X86fand FR32:$src1,
2621                                   (X86loadpf32 addr:$src2)))]>,
2622               Requires<[HasSSE1]>, TB;
2623 def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
2624                 "andpd {$src2, $dst|$dst, $src2}",
2625                 [(set FR64:$dst, (X86fand FR64:$src1,
2626                                   (X86loadpf64 addr:$src2)))]>,
2627               Requires<[HasSSE2]>, TB, OpSize;
2628 def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
2629                 "orps {$src2, $dst|$dst, $src2}", []>,
2630              Requires<[HasSSE1]>, TB;
2631 def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
2632                 "orpd {$src2, $dst|$dst, $src2}", []>,
2633              Requires<[HasSSE2]>, TB, OpSize;
2634 def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
2635                 "xorps {$src2, $dst|$dst, $src2}",
2636                 [(set FR32:$dst, (X86fxor FR32:$src1,
2637                                   (X86loadpf32 addr:$src2)))]>,
2638               Requires<[HasSSE1]>, TB;
2639 def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
2640                 "xorpd {$src2, $dst|$dst, $src2}",
2641                 [(set FR64:$dst, (X86fxor FR64:$src1,
2642                                   (X86loadpf64 addr:$src2)))]>,
2643               Requires<[HasSSE2]>, TB, OpSize;
2644
2645 def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2646                 "andnps {$src2, $dst|$dst, $src2}", []>,
2647                Requires<[HasSSE1]>, TB;
2648 def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
2649                 "andnps {$src2, $dst|$dst, $src2}", []>,
2650                Requires<[HasSSE1]>, TB;
2651 def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2652                 "andnpd {$src2, $dst|$dst, $src2}", []>,
2653                Requires<[HasSSE2]>, TB, OpSize;
2654 def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
2655                 "andnpd {$src2, $dst|$dst, $src2}", []>,
2656                Requires<[HasSSE2]>, TB, OpSize;
2657 }
2658
2659 //===----------------------------------------------------------------------===//
2660 // Floating Point Stack Support
2661 //===----------------------------------------------------------------------===//
2662
2663 // Floating point support.  All FP Stack operations are represented with two 
2664 // instructions here.  The first instruction, generated by the instruction
2665 // selector, uses "RFP" registers: a traditional register file to reference
2666 // floating point values.  These instructions are all psuedo instructions and
2667 // use the "Fp" prefix.  The second instruction is defined with FPI, which is
2668 // the actual instruction emitted by the assembler.  The FP stackifier pass
2669 // converts one to the other after register allocation occurs.
2670 //
2671 // Note that the FpI instruction should have instruction selection info (e.g.
2672 // a pattern) and the FPI instruction should have emission info (e.g. opcode
2673 // encoding and asm printing info).
2674
2675 // FPI - Floating Point Instruction template.
2676 class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
2677
2678 // FpI_ - Floating Point Psuedo Instruction template. Not Predicated.
2679 class FpI_<dag ops, FPFormat fp, list<dag> pattern>
2680   : X86Inst<0, Pseudo, NoImm, ops, ""> {
2681   let FPForm = fp; let FPFormBits = FPForm.Value;
2682   let Pattern = pattern;
2683 }
2684
2685 // Random Pseudo Instructions.
2686 def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP,
2687                   [(set RFP:$dst, X86fpget)]>;                    // FPR = ST(0)
2688
2689 let noResults = 1 in 
2690   def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP,
2691                         [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;   // ST(0) = FPR
2692
2693 // FpI - Floating Point Psuedo Instruction template. Predicated on FPStack.
2694 class FpI<dag ops, FPFormat fp, list<dag> pattern> :
2695   FpI_<ops, fp, pattern>, Requires<[FPStack]>;
2696
2697
2698 def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
2699
2700 // Arithmetic
2701 // Add, Sub, Mul, Div.
2702 def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2703                 [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
2704 def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2705                 [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>;
2706 def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2707                 [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>;
2708 def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2709                 [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>;
2710
2711 class FPST0rInst<bits<8> o, string asm>
2712   : FPI<o, AddRegFrm, (ops RST:$op), asm>, D8;
2713 class FPrST0Inst<bits<8> o, string asm>
2714   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DC;
2715 class FPrST0PInst<bits<8> o, string asm>
2716   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DE;
2717
2718 // Binary Ops with a memory source.
2719 def FpADD32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2720                     [(set RFP:$dst, (fadd RFP:$src1,
2721                                      (extloadf64f32 addr:$src2)))]>;
2722                 // ST(0) = ST(0) + [mem32]
2723 def FpADD64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2724                     [(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>;
2725                 // ST(0) = ST(0) + [mem64]
2726 def FpMUL32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2727                     [(set RFP:$dst, (fmul RFP:$src1,
2728                                      (extloadf64f32 addr:$src2)))]>;
2729                 // ST(0) = ST(0) * [mem32]
2730 def FpMUL64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2731                     [(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>;
2732                 // ST(0) = ST(0) * [mem64]
2733 def FpSUB32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2734                     [(set RFP:$dst, (fsub RFP:$src1,
2735                                     (extloadf64f32 addr:$src2)))]>;
2736                 // ST(0) = ST(0) - [mem32]
2737 def FpSUB64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2738                     [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
2739                 // ST(0) = ST(0) - [mem64]
2740 def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2741                     [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2),
2742                                      RFP:$src1))]>;
2743                 // ST(0) = [mem32] - ST(0)
2744 def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2745                     [(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>;
2746                 // ST(0) = [mem64] - ST(0)
2747 def FpDIV32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2748                     [(set RFP:$dst, (fdiv RFP:$src1,
2749                                     (extloadf64f32 addr:$src2)))]>;
2750                 // ST(0) = ST(0) / [mem32]
2751 def FpDIV64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2752                     [(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>;
2753                 // ST(0) = ST(0) / [mem64]
2754 def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2755                     [(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2),
2756                                      RFP:$src1))]>;
2757                 // ST(0) = [mem32] / ST(0)
2758 def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2759                     [(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>;
2760                 // ST(0) = [mem64] / ST(0)
2761
2762
2763 def FADD32m  : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
2764 def FADD64m  : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">;
2765 def FMUL32m  : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">;
2766 def FMUL64m  : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">;
2767 def FSUB32m  : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">;
2768 def FSUB64m  : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">;
2769 def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">;
2770 def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">;
2771 def FDIV32m  : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">;
2772 def FDIV64m  : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">;
2773 def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">;
2774 def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
2775
2776 def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2777                     [(set RFP:$dst, (fadd RFP:$src1,
2778                                      (X86fild addr:$src2, i16)))]>;
2779                 // ST(0) = ST(0) + [mem16int]
2780 def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2781                     [(set RFP:$dst, (fadd RFP:$src1,
2782                                      (X86fild addr:$src2, i32)))]>;
2783                 // ST(0) = ST(0) + [mem32int]
2784 def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2785                     [(set RFP:$dst, (fmul RFP:$src1,
2786                                      (X86fild addr:$src2, i16)))]>;
2787                 // ST(0) = ST(0) * [mem16int]
2788 def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2789                     [(set RFP:$dst, (fmul RFP:$src1,
2790                                      (X86fild addr:$src2, i32)))]>;
2791                 // ST(0) = ST(0) * [mem32int]
2792 def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2793                     [(set RFP:$dst, (fsub RFP:$src1,
2794                                      (X86fild addr:$src2, i16)))]>;
2795                 // ST(0) = ST(0) - [mem16int]
2796 def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2797                     [(set RFP:$dst, (fsub RFP:$src1,
2798                                      (X86fild addr:$src2, i32)))]>;
2799                 // ST(0) = ST(0) - [mem32int]
2800 def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2801                      [(set RFP:$dst, (fsub (X86fild addr:$src2, i16),
2802                                       RFP:$src1))]>;
2803                 // ST(0) = [mem16int] - ST(0)
2804 def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2805                      [(set RFP:$dst, (fsub (X86fild addr:$src2, i32),
2806                                       RFP:$src1))]>;
2807                 // ST(0) = [mem32int] - ST(0)
2808 def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2809                     [(set RFP:$dst, (fdiv RFP:$src1,
2810                                      (X86fild addr:$src2, i16)))]>;
2811                 // ST(0) = ST(0) / [mem16int]
2812 def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2813                     [(set RFP:$dst, (fdiv RFP:$src1,
2814                                      (X86fild addr:$src2, i32)))]>;
2815                 // ST(0) = ST(0) / [mem32int]
2816 def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
2817                      [(set RFP:$dst, (fdiv (X86fild addr:$src2, i16),
2818                                       RFP:$src1))]>;
2819                 // ST(0) = [mem16int] / ST(0)
2820 def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
2821                      [(set RFP:$dst, (fdiv (X86fild addr:$src2, i32),
2822                                       RFP:$src1))]>;
2823                 // ST(0) = [mem32int] / ST(0)
2824
2825 def FIADD16m  : FPI<0xDE, MRM0m, (ops i16mem:$src), "fiadd{s} $src">;
2826 def FIADD32m  : FPI<0xDA, MRM0m, (ops i32mem:$src), "fiadd{l} $src">;
2827 def FIMUL16m  : FPI<0xDE, MRM1m, (ops i16mem:$src), "fimul{s} $src">;
2828 def FIMUL32m  : FPI<0xDA, MRM1m, (ops i32mem:$src), "fimul{l} $src">;
2829 def FISUB16m  : FPI<0xDE, MRM4m, (ops i16mem:$src), "fisub{s} $src">;
2830 def FISUB32m  : FPI<0xDA, MRM4m, (ops i32mem:$src), "fisub{l} $src">;
2831 def FISUBR16m : FPI<0xDE, MRM5m, (ops i16mem:$src), "fisubr{s} $src">;
2832 def FISUBR32m : FPI<0xDA, MRM5m, (ops i32mem:$src), "fisubr{l} $src">;
2833 def FIDIV16m  : FPI<0xDE, MRM6m, (ops i16mem:$src), "fidiv{s} $src">;
2834 def FIDIV32m  : FPI<0xDA, MRM6m, (ops i32mem:$src), "fidiv{l} $src">;
2835 def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">;
2836 def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $src">;
2837
2838 // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
2839 // of some of the 'reverse' forms of the fsub and fdiv instructions.  As such,
2840 // we have to put some 'r's in and take them out of weird places.
2841 def FADDST0r   : FPST0rInst <0xC0, "fadd $op">;
2842 def FADDrST0   : FPrST0Inst <0xC0, "fadd {%st(0), $op|$op, %ST(0)}">;
2843 def FADDPrST0  : FPrST0PInst<0xC0, "faddp $op">;
2844 def FSUBRST0r  : FPST0rInst <0xE8, "fsubr $op">;
2845 def FSUBrST0   : FPrST0Inst <0xE8, "fsub{r} {%st(0), $op|$op, %ST(0)}">;
2846 def FSUBPrST0  : FPrST0PInst<0xE8, "fsub{r}p $op">;
2847 def FSUBST0r   : FPST0rInst <0xE0, "fsub $op">;
2848 def FSUBRrST0  : FPrST0Inst <0xE0, "fsub{|r} {%st(0), $op|$op, %ST(0)}">;
2849 def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">;
2850 def FMULST0r   : FPST0rInst <0xC8, "fmul $op">;
2851 def FMULrST0   : FPrST0Inst <0xC8, "fmul {%st(0), $op|$op, %ST(0)}">;
2852 def FMULPrST0  : FPrST0PInst<0xC8, "fmulp $op">;
2853 def FDIVRST0r  : FPST0rInst <0xF8, "fdivr $op">;
2854 def FDIVrST0   : FPrST0Inst <0xF8, "fdiv{r} {%st(0), $op|$op, %ST(0)}">;
2855 def FDIVPrST0  : FPrST0PInst<0xF8, "fdiv{r}p $op">;
2856 def FDIVST0r   : FPST0rInst <0xF0, "fdiv $op">;
2857 def FDIVRrST0  : FPrST0Inst <0xF0, "fdiv{|r} {%st(0), $op|$op, %ST(0)}">;
2858 def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">;
2859
2860
2861 // Unary operations.
2862 def FpCHS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
2863                  [(set RFP:$dst, (fneg RFP:$src))]>;
2864 def FpABS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
2865                  [(set RFP:$dst, (fabs RFP:$src))]>;
2866 def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
2867                  [(set RFP:$dst, (fsqrt RFP:$src))]>;
2868 def FpSIN  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
2869                  [(set RFP:$dst, (fsin RFP:$src))]>;
2870 def FpCOS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
2871                  [(set RFP:$dst, (fcos RFP:$src))]>;
2872 def FpTST  : FpI<(ops RFP:$src), OneArgFP,
2873                  []>;
2874
2875 def FCHS  : FPI<0xE0, RawFrm, (ops), "fchs">, D9;
2876 def FABS  : FPI<0xE1, RawFrm, (ops), "fabs">, D9;
2877 def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9;
2878 def FSIN  : FPI<0xFE, RawFrm, (ops), "fsin">, D9;
2879 def FCOS  : FPI<0xFF, RawFrm, (ops), "fcos">, D9;
2880 def FTST  : FPI<0xE4, RawFrm, (ops), "ftst">, D9;
2881
2882
2883 // Floating point cmovs.
2884 let isTwoAddress = 1 in {
2885   def FpCMOVB  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2886                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2887                                       X86_COND_B))]>;
2888   def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2889                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2890                                       X86_COND_BE))]>;
2891   def FpCMOVE  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2892                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2893                                       X86_COND_E))]>;
2894   def FpCMOVP  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2895                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2896                                       X86_COND_P))]>;
2897   def FpCMOVNB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2898                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2899                                       X86_COND_AE))]>;
2900   def FpCMOVNBE: FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2901                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2902                                       X86_COND_A))]>;
2903   def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2904                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2905                                       X86_COND_NE))]>;
2906   def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
2907                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
2908                                       X86_COND_NP))]>;
2909 }
2910
2911 def FCMOVB  : FPI<0xC0, AddRegFrm, (ops RST:$op),
2912                   "fcmovb {$op, %st(0)|%ST(0), $op}">, DA;
2913 def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
2914                   "fcmovbe {$op, %st(0)|%ST(0), $op}">, DA;
2915 def FCMOVE  : FPI<0xC8, AddRegFrm, (ops RST:$op),
2916                   "fcmove {$op, %st(0)|%ST(0), $op}">, DA;
2917 def FCMOVP  : FPI<0xD8, AddRegFrm, (ops RST:$op),
2918                   "fcmovu  {$op, %st(0)|%ST(0), $op}">, DA;
2919 def FCMOVNB : FPI<0xC0, AddRegFrm, (ops RST:$op),
2920                   "fcmovnb {$op, %st(0)|%ST(0), $op}">, DB;
2921 def FCMOVNBE  : FPI<0xD0, AddRegFrm, (ops RST:$op),
2922                   "fcmovnbe {$op, %st(0)|%ST(0), $op}">, DB;
2923 def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op),
2924                   "fcmovne {$op, %st(0)|%ST(0), $op}">, DB;
2925 def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
2926                   "fcmovnu {$op, %st(0)|%ST(0), $op}">, DB;
2927
2928 // Floating point loads & stores.
2929 def FpLD32m  : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
2930                    [(set RFP:$dst, (extloadf64f32 addr:$src))]>;
2931 def FpLD64m  : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
2932                    [(set RFP:$dst, (loadf64 addr:$src))]>;
2933 def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
2934                    [(set RFP:$dst, (X86fild addr:$src, i16))]>;
2935 def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
2936                    [(set RFP:$dst, (X86fild addr:$src, i32))]>;
2937 def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
2938                    [(set RFP:$dst, (X86fild addr:$src, i64))]>;
2939
2940 def FpST32m   : FpI<(ops f32mem:$op, RFP:$src), OneArgFP,
2941                 [(truncstore RFP:$src, addr:$op, f32)]>;
2942 def FpST64m   : FpI<(ops f64mem:$op, RFP:$src), OneArgFP,
2943                 [(store RFP:$src, addr:$op)]>;
2944
2945 def FpSTP32m  : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
2946 def FpSTP64m  : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
2947 def FpIST16m  : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
2948 def FpIST32m  : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>;
2949 def FpIST64m  : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>;
2950
2951 def FLD32m   : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">;
2952 def FLD64m   : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">;
2953 def FILD16m  : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">;
2954 def FILD32m  : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">;
2955 def FILD64m  : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">;
2956 def FST32m   : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">;
2957 def FST64m   : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">;
2958 def FSTP32m  : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">;
2959 def FSTP64m  : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">;
2960 def FIST16m  : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">;
2961 def FIST32m  : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">;
2962 def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">;
2963 def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">;
2964 def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">;
2965
2966 // FP Stack manipulation instructions.
2967 def FLDrr   : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9;
2968 def FSTrr   : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD;
2969 def FSTPrr  : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
2970 def FXCH    : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
2971
2972 // Floating point constant loads.
2973 def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP,
2974                 [(set RFP:$dst, fp64imm0)]>;
2975 def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP,
2976                 [(set RFP:$dst, fp64imm1)]>;
2977
2978 def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
2979 def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
2980
2981
2982 // Floating point compares.
2983 def FpUCOMr   : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
2984                     []>;  // FPSW = cmp ST(0) with ST(i)
2985 def FpUCOMIr  : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
2986                     [(X86cmp RFP:$lhs, RFP:$rhs)]>; // CC = cmp ST(0) with ST(i)
2987
2988 def FUCOMr    : FPI<0xE0, AddRegFrm,    // FPSW = cmp ST(0) with ST(i)
2989                     (ops RST:$reg),
2990                     "fucom $reg">, DD, Imp<[ST0],[]>;
2991 def FUCOMPr   : FPI<0xE8, AddRegFrm,    // FPSW = cmp ST(0) with ST(i), pop
2992                   (ops RST:$reg),
2993                   "fucomp $reg">, DD, Imp<[ST0],[]>;
2994 def FUCOMPPr  : FPI<0xE9, RawFrm,       // cmp ST(0) with ST(1), pop, pop
2995                   (ops),
2996                   "fucompp">, DA, Imp<[ST0],[]>;
2997
2998 def FUCOMIr  : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i)
2999                    (ops RST:$reg),
3000                    "fucomi {$reg, %st(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>;
3001 def FUCOMIPr : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i), pop
3002                  (ops RST:$reg),
3003                  "fucomip {$reg, %st(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>;
3004
3005
3006 // Floating point flag ops.
3007 def FNSTSW8r  : I<0xE0, RawFrm,                  // AX = fp flags
3008                   (ops), "fnstsw", []>, DF, Imp<[],[AX]>;
3009
3010 def FNSTCW16m : I<0xD9, MRM7m,                   // [mem16] = X87 control world
3011                   (ops i16mem:$dst), "fnstcw $dst", []>;
3012 def FLDCW16m  : I<0xD9, MRM5m,                   // X87 control world = [mem16]
3013                   (ops i16mem:$dst), "fldcw $dst", []>;
3014
3015
3016 //===----------------------------------------------------------------------===//
3017 // XMM Packed Floating point support (requires SSE / SSE2)
3018 //===----------------------------------------------------------------------===//
3019
3020 def MOVAPSrr : I<0x28, MRMSrcMem, (ops V4F4:$dst, V4F4:$src),
3021                 "movaps {$src, $dst|$dst, $src}", []>,
3022                Requires<[HasSSE1]>, XS;
3023 def MOVAPDrr : I<0x28, MRMSrcMem, (ops V2F8:$dst, V2F8:$src),
3024                 "movapd {$src, $dst|$dst, $src}", []>,
3025                Requires<[HasSSE2]>, XD;
3026
3027 def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F4:$dst, f128mem:$src),
3028                 "movaps {$src, $dst|$dst, $src}", []>,
3029                Requires<[HasSSE1]>, XS;
3030 def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F4:$src),
3031                 "movaps {$src, $dst|$dst, $src}",[]>,
3032                Requires<[HasSSE1]>, XD;
3033 def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F8:$dst, f128mem:$src),
3034                 "movapd {$src, $dst|$dst, $src}", []>,
3035                Requires<[HasSSE1]>, XD;
3036 def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F8:$src),
3037                 "movapd {$src, $dst|$dst, $src}",[]>,
3038                Requires<[HasSSE2]>, XD;
3039
3040 // Pseudo-instructions to load FR32 / FR64 from f128mem using movaps / movapd.
3041 // Upper bits are disregarded.
3042 def MOVSAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src),
3043                   "movaps {$src, $dst|$dst, $src}",
3044                   [(set FR32:$dst, (X86loadpf32 addr:$src))]>,
3045                 Requires<[HasSSE1]>, XS;
3046 def MOVSAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src),
3047                   "movapd {$src, $dst|$dst, $src}",
3048                   [(set FR64:$dst, (X86loadpf64 addr:$src))]>,
3049                 Requires<[HasSSE1]>, XD;
3050
3051
3052 //===----------------------------------------------------------------------===//
3053 // Miscellaneous Instructions
3054 //===----------------------------------------------------------------------===//
3055
3056 def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
3057             TB, Imp<[],[EAX,EDX]>;
3058
3059
3060 //===----------------------------------------------------------------------===//
3061 // Non-Instruction Patterns
3062 //===----------------------------------------------------------------------===//
3063
3064 // GlobalAddress and ExternalSymbol
3065 def : Pat<(i32 globaladdr:$dst),  (MOV32ri tglobaladdr:$dst)>;
3066 def : Pat<(i32 externalsym:$dst), (MOV32ri texternalsym:$dst)>;
3067
3068 // Calls
3069 def : Pat<(X86call tglobaladdr:$dst),
3070           (CALLpcrel32 tglobaladdr:$dst)>;
3071 def : Pat<(X86call texternalsym:$dst),
3072           (CALLpcrel32 texternalsym:$dst)>;
3073
3074 // X86 specific add which produces a flag.
3075 def : Pat<(X86addflag R32:$src1, R32:$src2),
3076           (ADD32rr R32:$src1, R32:$src2)>;
3077 def : Pat<(X86addflag R32:$src1, (load addr:$src2)),
3078           (ADD32rm R32:$src1, addr:$src2)>;
3079 def : Pat<(X86addflag R32:$src1, imm:$src2),
3080           (ADD32ri R32:$src1, imm:$src2)>;
3081 def : Pat<(X86addflag R32:$src1, i32immSExt8:$src2),
3082           (ADD32ri8 R32:$src1, i32immSExt8:$src2)>;
3083
3084 def : Pat<(X86subflag R32:$src1, R32:$src2),
3085           (SUB32rr R32:$src1, R32:$src2)>;
3086 def : Pat<(X86subflag R32:$src1, (load addr:$src2)),
3087           (SUB32rm R32:$src1, addr:$src2)>;
3088 def : Pat<(X86subflag R32:$src1, imm:$src2),
3089           (SUB32ri R32:$src1, imm:$src2)>;
3090 def : Pat<(X86subflag R32:$src1, i32immSExt8:$src2),
3091           (SUB32ri8 R32:$src1, i32immSExt8:$src2)>;
3092
3093 def : Pat<(truncstore (i8 imm:$src), addr:$dst, i1), 
3094           (MOV8mi addr:$dst, imm:$src)>;
3095 def : Pat<(truncstore R8:$src, addr:$dst, i1), 
3096           (MOV8mr addr:$dst, R8:$src)>;
3097
3098 // {s|z}extload bool -> {s|z}extload byte
3099 def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>;
3100 def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>;
3101 def : Pat<(zextloadi8i1  addr:$src), (MOV8rm     addr:$src)>;
3102 def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
3103 def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
3104
3105 // extload bool -> extload byte
3106 def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
3107
3108 // anyext -> zext
3109 def : Pat<(i16 (anyext R8 :$src)), (MOVZX16rr8  R8 :$src)>;
3110 def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8  R8 :$src)>;
3111 def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
3112
3113 // Required for RET of f32 / f64 values.
3114 def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>;
3115 def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
3116
3117 // Required for CALL which return f32 / f64 values.
3118 def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>;
3119 def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>;
3120
3121 // Floating point constant -0.0 and -1.0
3122 def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
3123 def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
3124
3125 // Used to conv. i64 to f64 since there isn't a SSE version.
3126 def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>;
3127
3128 //===----------------------------------------------------------------------===//
3129 // Some peepholes
3130 //===----------------------------------------------------------------------===//
3131
3132 // (shl x, 1) ==> (add x, x)
3133 def : Pat<(shl R8 :$src1, (i8 1)), (ADD8rr  R8 :$src1, R8 :$src1)>;
3134 def : Pat<(shl R16:$src1, (i8 1)), (ADD16rr R16:$src1, R16:$src1)>;
3135 def : Pat<(shl R32:$src1, (i8 1)), (ADD32rr R32:$src1, R32:$src1)>;
3136
3137 // (or (x >> c) | (y << (32 - c))) ==> (shrd32 x, y, c)
3138 def : Pat<(or (srl R32:$src1, CL:$amt),
3139               (shl R32:$src2, (sub 32, CL:$amt))),
3140           (SHRD32rrCL R32:$src1, R32:$src2)>;
3141
3142 def : Pat<(store (or (srl (loadi32 addr:$dst), CL:$amt),
3143                      (shl R32:$src2, (sub 32, CL:$amt))), addr:$dst),
3144           (SHRD32mrCL addr:$dst, R32:$src2)>;
3145
3146 // (or (x << c) | (y >> (32 - c))) ==> (shld32 x, y, c)
3147 def : Pat<(or (shl R32:$src1, CL:$amt),
3148               (srl R32:$src2, (sub 32, CL:$amt))),
3149           (SHLD32rrCL R32:$src1, R32:$src2)>;
3150
3151 def : Pat<(store (or (shl (loadi32 addr:$dst), CL:$amt),
3152                      (srl R32:$src2, (sub 32, CL:$amt))), addr:$dst),
3153           (SHLD32mrCL addr:$dst, R32:$src2)>;
3154
3155 // (or (x >> c) | (y << (16 - c))) ==> (shrd16 x, y, c)
3156 def : Pat<(or (srl R16:$src1, CL:$amt),
3157               (shl R16:$src2, (sub 16, CL:$amt))),
3158           (SHRD16rrCL R16:$src1, R16:$src2)>;
3159
3160 def : Pat<(store (or (srl (loadi16 addr:$dst), CL:$amt),
3161                      (shl R16:$src2, (sub 16, CL:$amt))), addr:$dst),
3162           (SHRD16mrCL addr:$dst, R16:$src2)>;
3163
3164 // (or (x << c) | (y >> (16 - c))) ==> (shld16 x, y, c)
3165 def : Pat<(or (shl R16:$src1, CL:$amt),
3166               (srl R16:$src2, (sub 16, CL:$amt))),
3167           (SHLD16rrCL R16:$src1, R16:$src2)>;
3168
3169 def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt),
3170                      (srl R16:$src2, (sub 16, CL:$amt))), addr:$dst),
3171           (SHLD16mrCL addr:$dst, R16:$src2)>;