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