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