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