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