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