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