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