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