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