Two peepholes:
[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, SDNPOutFlag]>;
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, SDNPInFlag]>;
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 zextloadi8i1   : PatFrag<(ops node:$ptr), (i8  (zextload node:$ptr, i1))>;
347 def zextloadi16i1  : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i1))>;
348 def zextloadi32i1  : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i1))>;
349 def zextloadi16i8  : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>;
350 def zextloadi32i8  : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
351 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
352
353 def extloadi8i1    : PatFrag<(ops node:$ptr), (i8  (extload node:$ptr, i1))>;
354 def extloadf64f32  : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>;
355
356 //===----------------------------------------------------------------------===//
357 // Instruction templates...
358
359 class I<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
360   : X86Inst<o, f, NoImm, ops, asm> {
361   let Pattern = pattern;
362 }
363 class Ii8 <bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
364   : X86Inst<o, f, Imm8 , ops, asm> {
365   let Pattern = pattern;
366 }
367 class Ii16<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
368   : X86Inst<o, f, Imm16, ops, asm> {
369   let Pattern = pattern;
370 }
371 class Ii32<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
372   : X86Inst<o, f, Imm32, ops, asm> {
373   let Pattern = pattern;
374 }
375
376 //===----------------------------------------------------------------------===//
377 // Instruction list...
378 //
379
380 // Pseudo-instructions:
381 def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE", []>;        // PHI node.
382
383 def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
384                          [(X86callseq_start imm:$amt)]>;
385 def ADJCALLSTACKUP   : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
386                          "#ADJCALLSTACKUP",
387                          [(X86callseq_end imm:$amt1, imm:$amt2)]>;
388 def IMPLICIT_USE     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
389 def IMPLICIT_DEF     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
390 def IMPLICIT_DEF_R8  : I<0, Pseudo, (ops R8:$dst),
391                          "#IMPLICIT_DEF $dst",
392                          [(set R8:$dst, (undef))]>;
393 def IMPLICIT_DEF_R16  : I<0, Pseudo, (ops R16:$dst),
394                          "#IMPLICIT_DEF $dst",
395                          [(set R16:$dst, (undef))]>;
396 def IMPLICIT_DEF_R32  : I<0, Pseudo, (ops R32:$dst),
397                          "#IMPLICIT_DEF $dst",
398                          [(set R32:$dst, (undef))]>;
399 def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst),
400                          "#IMPLICIT_DEF $dst",
401                          [(set FR32:$dst, (undef))]>, Requires<[HasSSE2]>;
402 def IMPLICIT_DEF_FR64 : I<0, Pseudo, (ops FR64:$dst),
403                          "#IMPLICIT_DEF $dst",
404                          [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>;
405
406
407 // CMOV* - Used to implement the SSE SELECT DAG operation.  Expanded by the
408 // scheduler into a branch sequence.
409 let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
410   def CMOV_FR32 : I<0, Pseudo,
411                     (ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond),
412                     "#CMOV_FR32 PSEUDO!",
413                     [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond,
414                                       STATUS))]>;
415   def CMOV_FR64 : I<0, Pseudo,
416                     (ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond),
417                     "#CMOV_FR64 PSEUDO!",
418                     [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond,
419                                       STATUS))]>;
420 }
421
422 let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
423   def FP_TO_INT16_IN_MEM : I<0, Pseudo,
424                             (ops i16mem:$dst, RFP:$src),
425                            "#FP_TO_INT16_IN_MEM PSEUDO!",
426                            [(X86fp_to_i16mem RFP:$src, addr:$dst)]>;
427   def FP_TO_INT32_IN_MEM : I<0, Pseudo,
428                             (ops i32mem:$dst, RFP:$src),
429                            "#FP_TO_INT32_IN_MEM PSEUDO!",
430                            [(X86fp_to_i32mem RFP:$src, addr:$dst)]>;
431   def FP_TO_INT64_IN_MEM : I<0, Pseudo,
432                             (ops i64mem:$dst, RFP:$src),
433                            "#FP_TO_INT64_IN_MEM PSEUDO!",
434                            [(X86fp_to_i64mem RFP:$src, addr:$dst)]>;
435 }
436
437
438 let isTerminator = 1 in
439   let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
440     def FP_REG_KILL  : I<0, Pseudo, (ops), "#FP_REG_KILL", []>;
441
442
443 // Nop
444 def NOOP : I<0x90, RawFrm, (ops), "nop", []>;
445
446 //===----------------------------------------------------------------------===//
447 //  Control Flow Instructions...
448 //
449
450 // Return instructions.
451 let isTerminator = 1, isReturn = 1, isBarrier = 1,
452     hasCtrlDep = 1, noResults = 1 in {
453   def RET    : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
454   def RETI   : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
455                     [(X86retflag imm:$amt)]>;
456 }
457
458 // All branches are RawFrm, Void, Branch, and Terminators
459 let isBranch = 1, isTerminator = 1, noResults = 1 in
460   class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
461         I<opcode, RawFrm, ops, asm, pattern>;
462
463 // Conditional branches
464 let isBarrier = 1 in
465   def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
466
467 def JE  : IBr<0x84, (ops brtarget:$dst), "je $dst",
468               [(X86brcond bb:$dst, X86_COND_E, STATUS)]>, Imp<[STATUS],[]>, TB;
469 def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
470               [(X86brcond bb:$dst, X86_COND_NE, STATUS)]>, Imp<[STATUS],[]>, TB;
471 def JL  : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
472               [(X86brcond bb:$dst, X86_COND_L, STATUS)]>, Imp<[STATUS],[]>, TB;
473 def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
474               [(X86brcond bb:$dst, X86_COND_LE, STATUS)]>, Imp<[STATUS],[]>, TB;
475 def JG  : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
476               [(X86brcond bb:$dst, X86_COND_G, STATUS)]>, Imp<[STATUS],[]>, TB;
477 def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
478               [(X86brcond bb:$dst, X86_COND_GE, STATUS)]>, Imp<[STATUS],[]>, TB;
479
480 def JB  : IBr<0x82, (ops brtarget:$dst), "jb $dst",
481               [(X86brcond bb:$dst, X86_COND_B, STATUS)]>, Imp<[STATUS],[]>, TB;
482 def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
483               [(X86brcond bb:$dst, X86_COND_BE, STATUS)]>, Imp<[STATUS],[]>, TB;
484 def JA  : IBr<0x87, (ops brtarget:$dst), "ja $dst",
485               [(X86brcond bb:$dst, X86_COND_A, STATUS)]>, Imp<[STATUS],[]>, TB;
486 def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
487               [(X86brcond bb:$dst, X86_COND_AE, STATUS)]>, Imp<[STATUS],[]>, TB;
488
489 def JS  : IBr<0x88, (ops brtarget:$dst), "js $dst",
490               [(X86brcond bb:$dst, X86_COND_S, STATUS)]>, Imp<[STATUS],[]>, TB;
491 def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst",
492               [(X86brcond bb:$dst, X86_COND_NS, STATUS)]>, Imp<[STATUS],[]>, TB;
493 def JP  : IBr<0x8A, (ops brtarget:$dst), "jp $dst",
494               [(X86brcond bb:$dst, X86_COND_P, STATUS)]>, Imp<[STATUS],[]>, TB;
495 def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst",
496               [(X86brcond bb:$dst, X86_COND_NP, STATUS)]>, Imp<[STATUS],[]>, TB;
497 def JO  : IBr<0x80, (ops brtarget:$dst), "jo $dst",
498               [(X86brcond bb:$dst, X86_COND_O, STATUS)]>, Imp<[STATUS],[]>, TB;
499 def JNO : IBr<0x81, (ops brtarget:$dst), "jno $dst",
500               [(X86brcond bb:$dst, X86_COND_NO, STATUS)]>, Imp<[STATUS],[]>, TB;
501
502 //===----------------------------------------------------------------------===//
503 //  Call Instructions...
504 //
505 let isCall = 1, noResults = 1 in
506   // All calls clobber the non-callee saved registers...
507   let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
508               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
509     def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst",
510                       []>;
511     def CALL32r     : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst",
512                       [(X86call R32:$dst)]>;
513     def CALL32m     : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst",
514                       [(X86call (loadi32 addr:$dst))]>;
515   }
516
517 // Tail call stuff.
518 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
519   def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst  # TAIL CALL", []>;
520 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
521   def TAILJMPr : I<0xFF, MRM4r, (ops R32:$dst), "jmp {*}$dst  # TAIL CALL", []>;
522 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
523   def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
524                    "jmp {*}$dst  # TAIL CALL", []>;
525
526 // ADJSTACKPTRri - This is a standard ADD32ri instruction, identical in every
527 // way, except that it is marked as being a terminator.  This causes the epilog
528 // inserter to insert reloads of callee saved registers BEFORE this.  We need
529 // this until we have a more accurate way of tracking where the stack pointer is
530 // within a function.
531 let isTerminator = 1, isTwoAddress = 1 in
532   def ADJSTACKPTRri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
533                            "add{l} {$src2, $dst|$dst, $src2}", []>;
534
535 //===----------------------------------------------------------------------===//
536 //  Miscellaneous Instructions...
537 //
538 def LEAVE    : I<0xC9, RawFrm,
539                  (ops), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
540 def POP32r   : I<0x58, AddRegFrm,
541                  (ops R32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
542
543 let isTwoAddress = 1 in                               // R32 = bswap R32
544   def BSWAP32r : I<0xC8, AddRegFrm,
545                    (ops R32:$dst, R32:$src),
546                    "bswap{l} $dst", 
547                    [(set R32:$dst, (bswap R32:$src))]>, TB;
548
549 def XCHG8rr  : I<0x86, MRMDestReg,                    // xchg R8, R8
550                  (ops R8:$src1, R8:$src2),
551                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
552 def XCHG16rr : I<0x87, MRMDestReg,                    // xchg R16, R16
553                  (ops R16:$src1, R16:$src2),
554                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
555 def XCHG32rr : I<0x87, MRMDestReg,                    // xchg R32, R32
556                  (ops R32:$src1, R32:$src2),
557                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
558
559 def XCHG8mr  : I<0x86, MRMDestMem,
560                  (ops i8mem:$src1, R8:$src2),
561                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
562 def XCHG16mr : I<0x87, MRMDestMem,
563                  (ops i16mem:$src1, R16:$src2),
564                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
565 def XCHG32mr : I<0x87, MRMDestMem,
566                  (ops i32mem:$src1, R32:$src2),
567                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
568 def XCHG8rm  : I<0x86, MRMSrcMem,
569                  (ops R8:$src1, i8mem:$src2),
570                  "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
571 def XCHG16rm : I<0x87, MRMSrcMem,
572                  (ops R16:$src1, i16mem:$src2),
573                  "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
574 def XCHG32rm : I<0x87, MRMSrcMem,
575                  (ops R32:$src1, i32mem:$src2),
576                  "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
577
578 def LEA16r   : I<0x8D, MRMSrcMem,
579                  (ops R16:$dst, i32mem:$src),
580                  "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
581 def LEA32r   : I<0x8D, MRMSrcMem,
582                  (ops R32:$dst, i32mem:$src),
583                  "lea{l} {$src|$dst}, {$dst|$src}",
584                  [(set R32:$dst, leaaddr:$src)]>;
585
586 def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}",
587                   [(X86rep_movs i8)]>,
588                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
589 def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}",
590                   [(X86rep_movs i16)]>,
591                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
592 def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}",
593                   [(X86rep_movs i32)]>,
594                 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
595
596 def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}",
597                   [(X86rep_stos i8)]>,
598                 Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
599 def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}",
600                   [(X86rep_stos i16)]>,
601                 Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
602 def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
603                   [(X86rep_stos i32)]>,
604                 Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
605
606
607 //===----------------------------------------------------------------------===//
608 //  Input/Output Instructions...
609 //
610 def IN8rr  : I<0xEC, RawFrm, (ops),
611                "in{b} {%dx, %al|%AL, %DX}",
612                [(set AL, (readport DX))]>,  Imp<[DX], [AL]>;
613 def IN16rr : I<0xED, RawFrm, (ops),
614                "in{w} {%dx, %ax|%AX, %DX}",
615                [(set AX, (readport DX))]>,  Imp<[DX], [AX]>, OpSize;
616 def IN32rr : I<0xED, RawFrm, (ops),
617                "in{l} {%dx, %eax|%EAX, %DX}",
618                [(set EAX, (readport DX))]>, Imp<[DX],[EAX]>;
619
620 def IN8ri  : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
621                   "in{b} {$port, %al|%AL, $port}",
622                  [(set AL, (readport i16immZExt8:$port))]>,
623              Imp<[], [AL]>;
624 def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
625                   "in{w} {$port, %ax|%AX, $port}",
626                  [(set AX, (readport i16immZExt8:$port))]>,
627              Imp<[], [AX]>, OpSize;
628 def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
629                   "in{l} {$port, %eax|%EAX, $port}",
630                  [(set EAX, (readport i16immZExt8:$port))]>,
631              Imp<[],[EAX]>;
632
633 def OUT8rr  : I<0xEE, RawFrm, (ops),
634                 "out{b} {%al, %dx|%DX, %AL}",
635                 [(writeport AL, DX)]>,  Imp<[DX,  AL], []>;
636 def OUT16rr : I<0xEF, RawFrm, (ops),
637                 "out{w} {%ax, %dx|%DX, %AX}",
638                 [(writeport AX, DX)]>,  Imp<[DX,  AX], []>, OpSize;
639 def OUT32rr : I<0xEF, RawFrm, (ops),
640                 "out{l} {%eax, %dx|%DX, %EAX}",
641                 [(writeport EAX, DX)]>, Imp<[DX, EAX], []>;
642
643 def OUT8ir  : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
644                    "out{b} {%al, $port|$port, %AL}",
645                    [(writeport AL, i16immZExt8:$port)]>,
646               Imp<[AL], []>;
647 def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
648                    "out{w} {%ax, $port|$port, %AX}",
649                    [(writeport AX, i16immZExt8:$port)]>,
650               Imp<[AX], []>, OpSize;
651 def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
652                    "out{l} {%eax, $port|$port, %EAX}",
653                    [(writeport EAX, i16immZExt8:$port)]>,
654               Imp<[EAX], []>;
655
656 //===----------------------------------------------------------------------===//
657 //  Move Instructions...
658 //
659 def MOV8rr  : I<0x88, MRMDestReg, (ops R8 :$dst, R8 :$src),
660                 "mov{b} {$src, $dst|$dst, $src}", []>;
661 def MOV16rr : I<0x89, MRMDestReg, (ops R16:$dst, R16:$src),
662                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
663 def MOV32rr : I<0x89, MRMDestReg, (ops R32:$dst, R32:$src),
664                 "mov{l} {$src, $dst|$dst, $src}", []>;
665 def MOV8ri  : Ii8 <0xB0, AddRegFrm, (ops R8 :$dst, i8imm :$src),
666                    "mov{b} {$src, $dst|$dst, $src}",
667                    [(set R8:$dst, imm:$src)]>;
668 def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src),
669                    "mov{w} {$src, $dst|$dst, $src}",
670                    [(set R16:$dst, imm:$src)]>, OpSize;
671 def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src),
672                    "mov{l} {$src, $dst|$dst, $src}",
673                    [(set R32:$dst, imm:$src)]>;
674 def MOV8mi  : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
675                    "mov{b} {$src, $dst|$dst, $src}",
676                    [(store (i8 imm:$src), addr:$dst)]>;
677 def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src),
678                    "mov{w} {$src, $dst|$dst, $src}",
679                    [(store (i16 imm:$src), addr:$dst)]>, OpSize;
680 def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src),
681                    "mov{l} {$src, $dst|$dst, $src}",
682                    [(store (i32 imm:$src), addr:$dst)]>;
683
684 def MOV8rm  : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src),
685                 "mov{b} {$src, $dst|$dst, $src}",
686                 [(set R8:$dst, (load addr:$src))]>;
687 def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src),
688                 "mov{w} {$src, $dst|$dst, $src}",
689                 [(set R16:$dst, (load addr:$src))]>, OpSize;
690 def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src),
691                 "mov{l} {$src, $dst|$dst, $src}",
692                 [(set R32:$dst, (load addr:$src))]>;
693
694 def MOV8mr  : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src),
695                 "mov{b} {$src, $dst|$dst, $src}",
696                 [(store R8:$src, addr:$dst)]>;
697 def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16:$src),
698                 "mov{w} {$src, $dst|$dst, $src}",
699                 [(store R16:$src, addr:$dst)]>, OpSize;
700 def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src),
701                 "mov{l} {$src, $dst|$dst, $src}",
702                 [(store R32:$src, addr:$dst)]>;
703                 
704 //===----------------------------------------------------------------------===//
705 //  Fixed-Register Multiplication and Division Instructions...
706 //
707
708 // Extra precision multiplication
709 def MUL8r  : I<0xF6, MRM4r, (ops R8:$src), "mul{b} $src",
710                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
711                // This probably ought to be moved to a def : Pat<> if the
712                // syntax can be accepted.
713                [(set AL, (mul AL, R8:$src))]>,
714              Imp<[AL],[AX]>;               // AL,AH = AL*R8
715 def MUL16r : I<0xF7, MRM4r, (ops R16:$src), "mul{w} $src", []>,
716              Imp<[AX],[AX,DX]>, OpSize;    // AX,DX = AX*R16
717 def MUL32r : I<0xF7, MRM4r, (ops R32:$src), "mul{l} $src", []>,
718              Imp<[EAX],[EAX,EDX]>;         // EAX,EDX = EAX*R32
719 def MUL8m  : I<0xF6, MRM4m, (ops i8mem :$src),
720                "mul{b} $src",
721                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
722                // This probably ought to be moved to a def : Pat<> if the
723                // syntax can be accepted.
724                [(set AL, (mul AL, (loadi8 addr:$src)))]>,
725              Imp<[AL],[AX]>;          // AL,AH = AL*[mem8]
726 def MUL16m : I<0xF7, MRM4m, (ops i16mem:$src),
727                "mul{w} $src", []>, Imp<[AX],[AX,DX]>,
728                OpSize; // AX,DX = AX*[mem16]
729 def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src),
730                "mul{l} $src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
731
732 def IMUL8r  : I<0xF6, MRM5r, (ops R8:$src), "imul{b} $src", []>,
733               Imp<[AL],[AX]>;               // AL,AH = AL*R8
734 def IMUL16r : I<0xF7, MRM5r, (ops R16:$src), "imul{w} $src", []>,
735               Imp<[AX],[AX,DX]>, OpSize;    // AX,DX = AX*R16
736 def IMUL32r : I<0xF7, MRM5r, (ops R32:$src), "imul{l} $src", []>,
737               Imp<[EAX],[EAX,EDX]>;         // EAX,EDX = EAX*R32
738 def IMUL8m  : I<0xF6, MRM5m, (ops i8mem :$src),
739                 "imul{b} $src", []>, Imp<[AL],[AX]>;        // AL,AH = AL*[mem8]
740 def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src),
741                 "imul{w} $src", []>, Imp<[AX],[AX,DX]>,
742                 OpSize; // AX,DX = AX*[mem16]
743 def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src),
744                 "imul{l} $src", []>,
745                 Imp<[EAX],[EAX,EDX]>;  // EAX,EDX = EAX*[mem32]
746
747 // unsigned division/remainder
748 def DIV8r  : I<0xF6, MRM6r, (ops R8:$src),          // AX/r8 = AL,AH
749                "div{b} $src", []>, Imp<[AX],[AX]>;
750 def DIV16r : I<0xF7, MRM6r, (ops R16:$src),         // DX:AX/r16 = AX,DX
751                "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
752 def DIV32r : I<0xF7, MRM6r, (ops R32:$src),         // EDX:EAX/r32 = EAX,EDX
753                "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
754 def DIV8m  : I<0xF6, MRM6m, (ops i8mem:$src),       // AX/[mem8] = AL,AH
755                "div{b} $src", []>, Imp<[AX],[AX]>;
756 def DIV16m : I<0xF7, MRM6m, (ops i16mem:$src),      // DX:AX/[mem16] = AX,DX
757                "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
758 def DIV32m : I<0xF7, MRM6m, (ops i32mem:$src),      // EDX:EAX/[mem32] = EAX,EDX
759                "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
760
761 // Signed division/remainder.
762 def IDIV8r : I<0xF6, MRM7r, (ops R8:$src),          // AX/r8 = AL,AH
763                "idiv{b} $src", []>, Imp<[AX],[AX]>;
764 def IDIV16r: I<0xF7, MRM7r, (ops R16:$src),         // DX:AX/r16 = AX,DX
765                "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
766 def IDIV32r: I<0xF7, MRM7r, (ops R32:$src),         // EDX:EAX/r32 = EAX,EDX
767                "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
768 def IDIV8m : I<0xF6, MRM7m, (ops i8mem:$src),      // AX/[mem8] = AL,AH
769                "idiv{b} $src", []>, Imp<[AX],[AX]>;
770 def IDIV16m: I<0xF7, MRM7m, (ops i16mem:$src),     // DX:AX/[mem16] = AX,DX
771                "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
772 def IDIV32m: I<0xF7, MRM7m, (ops i32mem:$src),     // EDX:EAX/[mem32] = EAX,EDX
773                "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
774
775 // Sign-extenders for division.
776 def CBW : I<0x98, RawFrm, (ops),
777             "{cbtw|cbw}", []>, Imp<[AL],[AH]>;   // AX = signext(AL)
778 def CWD : I<0x99, RawFrm, (ops),
779             "{cwtd|cwd}", []>, Imp<[AX],[DX]>;   // DX:AX = signext(AX)
780 def CDQ : I<0x99, RawFrm, (ops),
781             "{cltd|cdq}", []>, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
782           
783
784 //===----------------------------------------------------------------------===//
785 //  Two address Instructions...
786 //
787 let isTwoAddress = 1 in {
788
789 // Conditional moves
790 def CMOVB16rr : I<0x42, MRMSrcReg,       // if <u, R16 = R16
791                   (ops R16:$dst, R16:$src1, R16:$src2),
792                   "cmovb {$src2, $dst|$dst, $src2}",
793                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
794                                    X86_COND_B, STATUS))]>,
795                   Imp<[STATUS],[]>, TB, OpSize;
796 def CMOVB16rm : I<0x42, MRMSrcMem,       // if <u, R16 = [mem16]
797                   (ops R16:$dst, R16:$src1, i16mem:$src2),
798                   "cmovb {$src2, $dst|$dst, $src2}",
799                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
800                                    X86_COND_B, STATUS))]>,
801                   Imp<[STATUS],[]>, TB, OpSize;
802 def CMOVB32rr : I<0x42, MRMSrcReg,       // if <u, R32 = R32
803                   (ops R32:$dst, R32:$src1, R32:$src2),
804                   "cmovb {$src2, $dst|$dst, $src2}",
805                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
806                                    X86_COND_B, STATUS))]>,
807                   Imp<[STATUS],[]>,  TB;
808 def CMOVB32rm : I<0x42, MRMSrcMem,       // if <u, R32 = [mem32]
809                   (ops R32:$dst, R32:$src1, i32mem:$src2),
810                   "cmovb {$src2, $dst|$dst, $src2}",
811                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
812                                    X86_COND_B, STATUS))]>,
813                   Imp<[STATUS],[]>,  TB;
814
815 def CMOVAE16rr: I<0x43, MRMSrcReg,       // if >=u, R16 = R16
816                   (ops R16:$dst, R16:$src1, R16:$src2),
817                   "cmovae {$src2, $dst|$dst, $src2}",
818                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
819                                    X86_COND_AE, STATUS))]>,
820                   Imp<[STATUS],[]>,  TB, OpSize;
821 def CMOVAE16rm: I<0x43, MRMSrcMem,       // if >=u, R16 = [mem16]
822                   (ops R16:$dst, R16:$src1, i16mem:$src2),
823                   "cmovae {$src2, $dst|$dst, $src2}",
824                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
825                                    X86_COND_AE, STATUS))]>,
826                   Imp<[STATUS],[]>,  TB, OpSize;
827 def CMOVAE32rr: I<0x43, MRMSrcReg,       // if >=u, R32 = R32
828                   (ops R32:$dst, R32:$src1, R32:$src2),
829                   "cmovae {$src2, $dst|$dst, $src2}",
830                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
831                                    X86_COND_AE, STATUS))]>,
832                   Imp<[STATUS],[]>,  TB;
833 def CMOVAE32rm: I<0x43, MRMSrcMem,       // if >=u, R32 = [mem32]
834                   (ops R32:$dst, R32:$src1, i32mem:$src2),
835                   "cmovae {$src2, $dst|$dst, $src2}",
836                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
837                                    X86_COND_AE, STATUS))]>,
838                   Imp<[STATUS],[]>,  TB;
839
840 def CMOVE16rr : I<0x44, MRMSrcReg,       // if ==, R16 = R16
841                   (ops R16:$dst, R16:$src1, R16:$src2),
842                   "cmove {$src2, $dst|$dst, $src2}",
843                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
844                                    X86_COND_E, STATUS))]>,
845                   Imp<[STATUS],[]>,  TB, OpSize;
846 def CMOVE16rm : I<0x44, MRMSrcMem,       // if ==, R16 = [mem16]
847                   (ops R16:$dst, R16:$src1, i16mem:$src2),
848                   "cmove {$src2, $dst|$dst, $src2}",
849                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
850                                    X86_COND_E, STATUS))]>,
851                   Imp<[STATUS],[]>,  TB, OpSize;
852 def CMOVE32rr : I<0x44, MRMSrcReg,       // if ==, R32 = R32
853                   (ops R32:$dst, R32:$src1, R32:$src2),
854                   "cmove {$src2, $dst|$dst, $src2}",
855                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
856                                    X86_COND_E, STATUS))]>,
857                   Imp<[STATUS],[]>,  TB;
858 def CMOVE32rm : I<0x44, MRMSrcMem,       // if ==, R32 = [mem32]
859                   (ops R32:$dst, R32:$src1, i32mem:$src2),
860                   "cmove {$src2, $dst|$dst, $src2}",
861                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
862                                    X86_COND_E, STATUS))]>,
863                   Imp<[STATUS],[]>,  TB;
864
865 def CMOVNE16rr: I<0x45, MRMSrcReg,       // if !=, R16 = R16
866                   (ops R16:$dst, R16:$src1, R16:$src2),
867                   "cmovne {$src2, $dst|$dst, $src2}",
868                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
869                                    X86_COND_NE, STATUS))]>,
870                   Imp<[STATUS],[]>,  TB, OpSize;
871 def CMOVNE16rm: I<0x45, MRMSrcMem,       // if !=, R16 = [mem16]
872                   (ops R16:$dst, R16:$src1, i16mem:$src2),
873                   "cmovne {$src2, $dst|$dst, $src2}",
874                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
875                                    X86_COND_NE, STATUS))]>,
876                   Imp<[STATUS],[]>,  TB, OpSize;
877 def CMOVNE32rr: I<0x45, MRMSrcReg,       // if !=, R32 = R32
878                   (ops R32:$dst, R32:$src1, R32:$src2),
879                   "cmovne {$src2, $dst|$dst, $src2}",
880                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
881                                    X86_COND_NE, STATUS))]>,
882                   Imp<[STATUS],[]>,  TB;
883 def CMOVNE32rm: I<0x45, MRMSrcMem,       // if !=, R32 = [mem32]
884                   (ops R32:$dst, R32:$src1, i32mem:$src2),
885                   "cmovne {$src2, $dst|$dst, $src2}",
886                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
887                                    X86_COND_NE, STATUS))]>,
888                   Imp<[STATUS],[]>,  TB;
889
890 def CMOVBE16rr: I<0x46, MRMSrcReg,       // if <=u, R16 = R16
891                   (ops R16:$dst, R16:$src1, R16:$src2),
892                   "cmovbe {$src2, $dst|$dst, $src2}",
893                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
894                                    X86_COND_BE, STATUS))]>,
895                   Imp<[STATUS],[]>,  TB, OpSize;
896 def CMOVBE16rm: I<0x46, MRMSrcMem,       // if <=u, R16 = [mem16]
897                   (ops R16:$dst, R16:$src1, i16mem:$src2),
898                   "cmovbe {$src2, $dst|$dst, $src2}",
899                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
900                                    X86_COND_BE, STATUS))]>,
901                   Imp<[STATUS],[]>,  TB, OpSize;
902 def CMOVBE32rr: I<0x46, MRMSrcReg,       // if <=u, R32 = R32
903                   (ops R32:$dst, R32:$src1, R32:$src2),
904                   "cmovbe {$src2, $dst|$dst, $src2}",
905                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
906                                    X86_COND_BE, STATUS))]>,
907                   Imp<[STATUS],[]>,  TB;
908 def CMOVBE32rm: I<0x46, MRMSrcMem,       // if <=u, R32 = [mem32]
909                   (ops R32:$dst, R32:$src1, i32mem:$src2),
910                   "cmovbe {$src2, $dst|$dst, $src2}",
911                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
912                                    X86_COND_BE, STATUS))]>,
913                   Imp<[STATUS],[]>,  TB;
914
915 def CMOVA16rr : I<0x47, MRMSrcReg,       // if >u, R16 = R16
916                   (ops R16:$dst, R16:$src1, R16:$src2),
917                   "cmova {$src2, $dst|$dst, $src2}",
918                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
919                                    X86_COND_A, STATUS))]>,
920                   Imp<[STATUS],[]>,  TB, OpSize;
921 def CMOVA16rm : I<0x47, MRMSrcMem,       // if >u, R16 = [mem16]
922                   (ops R16:$dst, R16:$src1, i16mem:$src2),
923                   "cmova {$src2, $dst|$dst, $src2}",
924                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
925                                    X86_COND_A, STATUS))]>,
926                   Imp<[STATUS],[]>,  TB, OpSize;
927 def CMOVA32rr : I<0x47, MRMSrcReg,       // if >u, R32 = R32
928                   (ops R32:$dst, R32:$src1, R32:$src2),
929                   "cmova {$src2, $dst|$dst, $src2}",
930                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
931                                    X86_COND_A, STATUS))]>,
932                   Imp<[STATUS],[]>,  TB;
933 def CMOVA32rm : I<0x47, MRMSrcMem,       // if >u, R32 = [mem32]
934                   (ops R32:$dst, R32:$src1, i32mem:$src2),
935                   "cmova {$src2, $dst|$dst, $src2}",
936                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
937                                    X86_COND_A, STATUS))]>,
938                   Imp<[STATUS],[]>,  TB;
939
940 def CMOVL16rr : I<0x4C, MRMSrcReg,       // if <s, R16 = R16
941                   (ops R16:$dst, R16:$src1, R16:$src2),
942                   "cmovl {$src2, $dst|$dst, $src2}",
943                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
944                                    X86_COND_L, STATUS))]>,
945                   Imp<[STATUS],[]>,  TB, OpSize;
946 def CMOVL16rm : I<0x4C, MRMSrcMem,       // if <s, R16 = [mem16]
947                   (ops R16:$dst, R16:$src1, i16mem:$src2),
948                   "cmovl {$src2, $dst|$dst, $src2}",
949                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
950                                    X86_COND_L, STATUS))]>,
951                   Imp<[STATUS],[]>,  TB, OpSize;
952 def CMOVL32rr : I<0x4C, MRMSrcReg,       // if <s, R32 = R32
953                   (ops R32:$dst, R32:$src1, R32:$src2),
954                   "cmovl {$src2, $dst|$dst, $src2}",
955                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
956                                    X86_COND_L, STATUS))]>,
957                   Imp<[STATUS],[]>,  TB;
958 def CMOVL32rm : I<0x4C, MRMSrcMem,       // if <s, R32 = [mem32]
959                   (ops R32:$dst, R32:$src1, i32mem:$src2),
960                   "cmovl {$src2, $dst|$dst, $src2}",
961                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
962                                    X86_COND_L, STATUS))]>,
963                   Imp<[STATUS],[]>,  TB;
964
965 def CMOVGE16rr: I<0x4D, MRMSrcReg,       // if >=s, R16 = R16
966                   (ops R16:$dst, R16:$src1, R16:$src2),
967                   "cmovge {$src2, $dst|$dst, $src2}",
968                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
969                                    X86_COND_GE, STATUS))]>,
970                   Imp<[STATUS],[]>,  TB, OpSize;
971 def CMOVGE16rm: I<0x4D, MRMSrcMem,       // if >=s, R16 = [mem16]
972                   (ops R16:$dst, R16:$src1, i16mem:$src2),
973                   "cmovge {$src2, $dst|$dst, $src2}",
974                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
975                                    X86_COND_GE, STATUS))]>,
976                   Imp<[STATUS],[]>,  TB, OpSize;
977 def CMOVGE32rr: I<0x4D, MRMSrcReg,       // if >=s, R32 = R32
978                   (ops R32:$dst, R32:$src1, R32:$src2),
979                   "cmovge {$src2, $dst|$dst, $src2}",
980                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
981                                    X86_COND_GE, STATUS))]>,
982                   Imp<[STATUS],[]>,  TB;
983 def CMOVGE32rm: I<0x4D, MRMSrcMem,       // if >=s, R32 = [mem32]
984                   (ops R32:$dst, R32:$src1, i32mem:$src2),
985                   "cmovge {$src2, $dst|$dst, $src2}",
986                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
987                                    X86_COND_GE, STATUS))]>,
988                   Imp<[STATUS],[]>,  TB;
989
990 def CMOVLE16rr: I<0x4E, MRMSrcReg,       // if <=s, R16 = R16
991                   (ops R16:$dst, R16:$src1, R16:$src2),
992                   "cmovle {$src2, $dst|$dst, $src2}",
993                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
994                                    X86_COND_LE, STATUS))]>,
995                   Imp<[STATUS],[]>,  TB, OpSize;
996 def CMOVLE16rm: I<0x4E, MRMSrcMem,       // if <=s, R16 = [mem16]
997                   (ops R16:$dst, R16:$src1, i16mem:$src2),
998                   "cmovle {$src2, $dst|$dst, $src2}",
999                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1000                                    X86_COND_LE, STATUS))]>,
1001                   Imp<[STATUS],[]>,  TB, OpSize;
1002 def CMOVLE32rr: I<0x4E, MRMSrcReg,       // if <=s, R32 = R32
1003                   (ops R32:$dst, R32:$src1, R32:$src2),
1004                   "cmovle {$src2, $dst|$dst, $src2}",
1005                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1006                                    X86_COND_LE, STATUS))]>,
1007                   Imp<[STATUS],[]>,  TB;
1008 def CMOVLE32rm: I<0x4E, MRMSrcMem,       // if <=s, R32 = [mem32]
1009                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1010                   "cmovle {$src2, $dst|$dst, $src2}",
1011                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1012                                    X86_COND_LE, STATUS))]>,
1013                   Imp<[STATUS],[]>,  TB;
1014
1015 def CMOVG16rr : I<0x4F, MRMSrcReg,       // if >s, R16 = R16
1016                   (ops R16:$dst, R16:$src1, R16:$src2),
1017                   "cmovg {$src2, $dst|$dst, $src2}",
1018                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1019                                    X86_COND_G, STATUS))]>,
1020                   Imp<[STATUS],[]>,  TB, OpSize;
1021 def CMOVG16rm : I<0x4F, MRMSrcMem,       // if >s, R16 = [mem16]
1022                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1023                   "cmovg {$src2, $dst|$dst, $src2}",
1024                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1025                                    X86_COND_G, STATUS))]>,
1026                   Imp<[STATUS],[]>,  TB, OpSize;
1027 def CMOVG32rr : I<0x4F, MRMSrcReg,       // if >s, R32 = R32
1028                   (ops R32:$dst, R32:$src1, R32:$src2),
1029                   "cmovg {$src2, $dst|$dst, $src2}",
1030                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1031                                    X86_COND_G, STATUS))]>,
1032                   Imp<[STATUS],[]>,  TB;
1033 def CMOVG32rm : I<0x4F, MRMSrcMem,       // if >s, R32 = [mem32]
1034                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1035                   "cmovg {$src2, $dst|$dst, $src2}",
1036                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1037                                    X86_COND_G, STATUS))]>,
1038                   Imp<[STATUS],[]>,  TB;
1039
1040 def CMOVS16rr : I<0x48, MRMSrcReg,       // if signed, R16 = R16
1041                   (ops R16:$dst, R16:$src1, R16:$src2),
1042                   "cmovs {$src2, $dst|$dst, $src2}",
1043                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1044                                    X86_COND_S, STATUS))]>,
1045                   Imp<[STATUS],[]>, TB, OpSize;
1046 def CMOVS16rm : I<0x48, MRMSrcMem,       // if signed, R16 = [mem16]
1047                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1048                   "cmovs {$src2, $dst|$dst, $src2}",
1049                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1050                                    X86_COND_S, STATUS))]>,
1051                   Imp<[STATUS],[]>, TB, OpSize;
1052 def CMOVS32rr : I<0x48, MRMSrcReg,       // if signed, R32 = R32
1053                   (ops R32:$dst, R32:$src1, R32:$src2),
1054                   "cmovs {$src2, $dst|$dst, $src2}",
1055                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1056                                    X86_COND_S, STATUS))]>,
1057                   Imp<[STATUS],[]>, TB;
1058 def CMOVS32rm : I<0x48, MRMSrcMem,       // if signed, R32 = [mem32]
1059                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1060                   "cmovs {$src2, $dst|$dst, $src2}",
1061                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1062                                    X86_COND_S, STATUS))]>,
1063                   Imp<[STATUS],[]>, TB;
1064
1065 def CMOVNS16rr: I<0x49, MRMSrcReg,       // if !signed, R16 = R16
1066                   (ops R16:$dst, R16:$src1, R16:$src2),
1067                   "cmovns {$src2, $dst|$dst, $src2}",
1068                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1069                                    X86_COND_NS, STATUS))]>,
1070                   Imp<[STATUS],[]>, TB, OpSize;
1071 def CMOVNS16rm: I<0x49, MRMSrcMem,       // if !signed, R16 = [mem16]
1072                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1073                   "cmovns {$src2, $dst|$dst, $src2}",
1074                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1075                                    X86_COND_NS, STATUS))]>,
1076                   Imp<[STATUS],[]>, TB, OpSize;
1077 def CMOVNS32rr: I<0x49, MRMSrcReg,       // if !signed, R32 = R32
1078                   (ops R32:$dst, R32:$src1, R32:$src2),
1079                   "cmovns {$src2, $dst|$dst, $src2}",
1080                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1081                                    X86_COND_NS, STATUS))]>,
1082                   Imp<[STATUS],[]>, TB;
1083 def CMOVNS32rm: I<0x49, MRMSrcMem,       // if !signed, R32 = [mem32]
1084                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1085                   "cmovns {$src2, $dst|$dst, $src2}",
1086                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1087                                    X86_COND_NS, STATUS))]>,
1088                   Imp<[STATUS],[]>, TB;
1089
1090 def CMOVP16rr : I<0x4A, MRMSrcReg,       // if parity, R16 = R16
1091                   (ops R16:$dst, R16:$src1, R16:$src2),
1092                   "cmovp {$src2, $dst|$dst, $src2}",
1093                   [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1094                                    X86_COND_P, STATUS))]>,
1095                   Imp<[STATUS],[]>, TB, OpSize;
1096 def CMOVP16rm : I<0x4A, MRMSrcMem,       // if parity, R16 = [mem16]
1097                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1098                   "cmovp {$src2, $dst|$dst, $src2}",
1099                   [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1100                                    X86_COND_P, STATUS))]>,
1101                   Imp<[STATUS],[]>, TB, OpSize;
1102 def CMOVP32rr : I<0x4A, MRMSrcReg,       // if parity, R32 = R32
1103                   (ops R32:$dst, R32:$src1, R32:$src2),
1104                   "cmovp {$src2, $dst|$dst, $src2}",
1105                   [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1106                                    X86_COND_P, STATUS))]>,
1107                   Imp<[STATUS],[]>, TB;
1108 def CMOVP32rm : I<0x4A, MRMSrcMem,       // if parity, R32 = [mem32]
1109                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1110                   "cmovp {$src2, $dst|$dst, $src2}",
1111                   [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1112                                    X86_COND_P, STATUS))]>,
1113                   Imp<[STATUS],[]>, TB;
1114
1115 def CMOVNP16rr : I<0x4B, MRMSrcReg,       // if !parity, R16 = R16
1116                   (ops R16:$dst, R16:$src1, R16:$src2),
1117                   "cmovnp {$src2, $dst|$dst, $src2}",
1118                    [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1119                                     X86_COND_NP, STATUS))]>,
1120                   Imp<[STATUS],[]>, TB, OpSize;
1121 def CMOVNP16rm : I<0x4B, MRMSrcMem,       // if !parity, R16 = [mem16]
1122                   (ops R16:$dst, R16:$src1, i16mem:$src2),
1123                   "cmovnp {$src2, $dst|$dst, $src2}",
1124                    [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1125                                     X86_COND_NP, STATUS))]>,
1126                   Imp<[STATUS],[]>, TB, OpSize;
1127 def CMOVNP32rr : I<0x4B, MRMSrcReg,       // if !parity, R32 = R32
1128                   (ops R32:$dst, R32:$src1, R32:$src2),
1129                   "cmovnp {$src2, $dst|$dst, $src2}",
1130                    [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1131                                     X86_COND_NP, STATUS))]>,
1132                   Imp<[STATUS],[]>, TB;
1133 def CMOVNP32rm : I<0x4B, MRMSrcMem,       // if !parity, R32 = [mem32]
1134                   (ops R32:$dst, R32:$src1, i32mem:$src2),
1135                   "cmovnp {$src2, $dst|$dst, $src2}",
1136                    [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1137                                    X86_COND_NP, STATUS))]>,
1138                   Imp<[STATUS],[]>, TB;
1139
1140
1141 // unary instructions
1142 def NEG8r  : I<0xF6, MRM3r, (ops R8 :$dst, R8 :$src), "neg{b} $dst",
1143                [(set R8:$dst, (ineg R8:$src))]>;
1144 def NEG16r : I<0xF7, MRM3r, (ops R16:$dst, R16:$src), "neg{w} $dst",
1145                [(set R16:$dst, (ineg R16:$src))]>, OpSize;
1146 def NEG32r : I<0xF7, MRM3r, (ops R32:$dst, R32:$src), "neg{l} $dst",
1147                [(set R32:$dst, (ineg R32:$src))]>;
1148 let isTwoAddress = 0 in {
1149   def NEG8m  : I<0xF6, MRM3m, (ops i8mem :$dst), "neg{b} $dst",
1150                  [(store (ineg (loadi8 addr:$dst)), addr:$dst)]>;
1151   def NEG16m : I<0xF7, MRM3m, (ops i16mem:$dst), "neg{w} $dst",
1152                  [(store (ineg (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1153   def NEG32m : I<0xF7, MRM3m, (ops i32mem:$dst), "neg{l} $dst",
1154                  [(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
1155
1156 }
1157
1158 def NOT8r  : I<0xF6, MRM2r, (ops R8 :$dst, R8 :$src), "not{b} $dst",
1159                [(set R8:$dst, (not R8:$src))]>;
1160 def NOT16r : I<0xF7, MRM2r, (ops R16:$dst, R16:$src), "not{w} $dst",
1161                [(set R16:$dst, (not R16:$src))]>, OpSize;
1162 def NOT32r : I<0xF7, MRM2r, (ops R32:$dst, R32:$src), "not{l} $dst",
1163                [(set R32:$dst, (not R32:$src))]>;
1164 let isTwoAddress = 0 in {
1165   def NOT8m  : I<0xF6, MRM2m, (ops i8mem :$dst), "not{b} $dst",
1166                  [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
1167   def NOT16m : I<0xF7, MRM2m, (ops i16mem:$dst), "not{w} $dst",
1168                  [(store (not (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1169   def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst",
1170                  [(store (not (loadi32 addr:$dst)), addr:$dst)]>;
1171 }
1172
1173 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
1174 def INC8r  : I<0xFE, MRM0r, (ops R8 :$dst, R8 :$src), "inc{b} $dst",
1175                [(set R8:$dst, (add R8:$src, 1))]>;
1176 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1177 def INC16r : I<0xFF, MRM0r, (ops R16:$dst, R16:$src), "inc{w} $dst",
1178                [(set R16:$dst, (add R16:$src, 1))]>, OpSize;
1179 def INC32r : I<0xFF, MRM0r, (ops R32:$dst, R32:$src), "inc{l} $dst",
1180                [(set R32:$dst, (add R32:$src, 1))]>;
1181 }
1182 let isTwoAddress = 0 in {
1183   def INC8m  : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
1184                [(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
1185   def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
1186                [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
1187   def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
1188                [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
1189 }
1190
1191 def DEC8r  : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst",
1192                [(set R8:$dst, (add R8:$src, -1))]>;
1193 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1194 def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst",
1195                [(set R16:$dst, (add R16:$src, -1))]>, OpSize;
1196 def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst",
1197                [(set R32:$dst, (add R32:$src, -1))]>;
1198 }
1199
1200 let isTwoAddress = 0 in {
1201   def DEC8m  : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
1202                [(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
1203   def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
1204                [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
1205   def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
1206                [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
1207 }
1208
1209 // Logical operators...
1210 let isCommutable = 1 in {   // X = AND Y, Z   --> X = AND Z, Y
1211 def AND8rr   : I<0x20, MRMDestReg,
1212                 (ops R8 :$dst, R8 :$src1, R8 :$src2),
1213                 "and{b} {$src2, $dst|$dst, $src2}",
1214                 [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
1215 def AND16rr  : I<0x21, MRMDestReg,
1216                  (ops R16:$dst, R16:$src1, R16:$src2),
1217                  "and{w} {$src2, $dst|$dst, $src2}",
1218                  [(set R16:$dst, (and R16:$src1, R16:$src2))]>, OpSize;
1219 def AND32rr  : I<0x21, MRMDestReg, 
1220                  (ops R32:$dst, R32:$src1, R32:$src2),
1221                  "and{l} {$src2, $dst|$dst, $src2}",
1222                  [(set R32:$dst, (and R32:$src1, R32:$src2))]>;
1223 }
1224
1225 def AND8rm   : I<0x22, MRMSrcMem, 
1226                  (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1227                  "and{b} {$src2, $dst|$dst, $src2}",
1228                 [(set R8:$dst, (and R8:$src1, (load addr:$src2)))]>;
1229 def AND16rm  : I<0x23, MRMSrcMem, 
1230                  (ops R16:$dst, R16:$src1, i16mem:$src2),
1231                  "and{w} {$src2, $dst|$dst, $src2}",
1232                 [(set R16:$dst, (and R16:$src1, (load addr:$src2)))]>, OpSize;
1233 def AND32rm  : I<0x23, MRMSrcMem,
1234                  (ops R32:$dst, R32:$src1, i32mem:$src2),
1235                  "and{l} {$src2, $dst|$dst, $src2}",
1236                 [(set R32:$dst, (and R32:$src1, (load addr:$src2)))]>;
1237
1238 def AND8ri   : Ii8<0x80, MRM4r, 
1239                    (ops R8 :$dst, R8 :$src1, i8imm :$src2),
1240                    "and{b} {$src2, $dst|$dst, $src2}",
1241                    [(set R8:$dst, (and R8:$src1, imm:$src2))]>;
1242 def AND16ri  : Ii16<0x81, MRM4r, 
1243                     (ops R16:$dst, R16:$src1, i16imm:$src2),
1244                     "and{w} {$src2, $dst|$dst, $src2}",
1245                     [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize;
1246 def AND32ri  : Ii32<0x81, MRM4r, 
1247                     (ops R32:$dst, R32:$src1, i32imm:$src2),
1248                     "and{l} {$src2, $dst|$dst, $src2}",
1249                     [(set R32:$dst, (and R32:$src1, imm:$src2))]>;
1250 def AND16ri8 : Ii8<0x83, MRM4r, 
1251                    (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1252                    "and{w} {$src2, $dst|$dst, $src2}",
1253                    [(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
1254                    OpSize;
1255 def AND32ri8 : Ii8<0x83, MRM4r, 
1256                    (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1257                    "and{l} {$src2, $dst|$dst, $src2}",
1258                    [(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
1259
1260 let isTwoAddress = 0 in {
1261   def AND8mr   : I<0x20, MRMDestMem,
1262                    (ops i8mem :$dst, R8 :$src),
1263                    "and{b} {$src, $dst|$dst, $src}",
1264                    [(store (and (load addr:$dst), R8:$src), addr:$dst)]>;
1265   def AND16mr  : I<0x21, MRMDestMem,
1266                    (ops i16mem:$dst, R16:$src),
1267                    "and{w} {$src, $dst|$dst, $src}",
1268                    [(store (and (load addr:$dst), R16:$src), addr:$dst)]>,
1269                    OpSize;
1270   def AND32mr  : I<0x21, MRMDestMem,
1271                    (ops i32mem:$dst, R32:$src),
1272                    "and{l} {$src, $dst|$dst, $src}",
1273                    [(store (and (load addr:$dst), R32:$src), addr:$dst)]>;
1274   def AND8mi   : Ii8<0x80, MRM4m,
1275                      (ops i8mem :$dst, i8imm :$src),
1276                      "and{b} {$src, $dst|$dst, $src}",
1277                       [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1278   def AND16mi  : Ii16<0x81, MRM4m,
1279                       (ops i16mem:$dst, i16imm:$src),
1280                       "and{w} {$src, $dst|$dst, $src}",
1281                       [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1282                       OpSize;
1283   def AND32mi  : Ii32<0x81, MRM4m,
1284                       (ops i32mem:$dst, i32imm:$src),
1285                       "and{l} {$src, $dst|$dst, $src}",
1286                       [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1287   def AND16mi8 : Ii8<0x83, MRM4m,
1288                      (ops i16mem:$dst, i16i8imm :$src),
1289                      "and{w} {$src, $dst|$dst, $src}",
1290                 [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1291                      OpSize;
1292   def AND32mi8 : Ii8<0x83, MRM4m,
1293                      (ops i32mem:$dst, i32i8imm :$src),
1294                      "and{l} {$src, $dst|$dst, $src}",
1295                 [(store (and (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1296 }
1297
1298
1299 let isCommutable = 1 in {   // X = OR Y, Z   --> X = OR Z, Y
1300 def OR8rr    : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1301                  "or{b} {$src2, $dst|$dst, $src2}",
1302                  [(set R8:$dst, (or R8:$src1, R8:$src2))]>;
1303 def OR16rr   : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1304                  "or{w} {$src2, $dst|$dst, $src2}",
1305                  [(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
1306 def OR32rr   : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1307                  "or{l} {$src2, $dst|$dst, $src2}",
1308                  [(set R32:$dst, (or R32:$src1, R32:$src2))]>;
1309 }
1310 def OR8rm    : I<0x0A, MRMSrcMem , (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1311                  "or{b} {$src2, $dst|$dst, $src2}",
1312                 [(set R8:$dst, (or R8:$src1, (load addr:$src2)))]>;
1313 def OR16rm   : I<0x0B, MRMSrcMem , (ops R16:$dst, R16:$src1, i16mem:$src2),
1314                  "or{w} {$src2, $dst|$dst, $src2}",
1315                 [(set R16:$dst, (or R16:$src1, (load addr:$src2)))]>, OpSize;
1316 def OR32rm   : I<0x0B, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1317                  "or{l} {$src2, $dst|$dst, $src2}",
1318                 [(set R32:$dst, (or R32:$src1, (load addr:$src2)))]>;
1319
1320 def OR8ri    : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1321                     "or{b} {$src2, $dst|$dst, $src2}",
1322                     [(set R8:$dst, (or R8:$src1, imm:$src2))]>;
1323 def OR16ri   : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1324                     "or{w} {$src2, $dst|$dst, $src2}", 
1325                     [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize;
1326 def OR32ri   : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1327                     "or{l} {$src2, $dst|$dst, $src2}",
1328                     [(set R32:$dst, (or R32:$src1, imm:$src2))]>;
1329
1330 def OR16ri8  : Ii8<0x83, MRM1r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1331                    "or{w} {$src2, $dst|$dst, $src2}",
1332                    [(set R16:$dst, (or R16:$src1, i16immSExt8:$src2))]>, OpSize;
1333 def OR32ri8  : Ii8<0x83, MRM1r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1334                    "or{l} {$src2, $dst|$dst, $src2}",
1335                    [(set R32:$dst, (or R32:$src1, i32immSExt8:$src2))]>;
1336 let isTwoAddress = 0 in {
1337   def OR8mr  : I<0x08, MRMDestMem, (ops i8mem:$dst, R8:$src),
1338                  "or{b} {$src, $dst|$dst, $src}",
1339                  [(store (or (load addr:$dst), R8:$src), addr:$dst)]>;
1340   def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, R16:$src),
1341                  "or{w} {$src, $dst|$dst, $src}",
1342                  [(store (or (load addr:$dst), R16:$src), addr:$dst)]>, OpSize;
1343   def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, R32:$src),
1344                  "or{l} {$src, $dst|$dst, $src}",
1345                  [(store (or (load addr:$dst), R32:$src), addr:$dst)]>;
1346   def OR8mi    : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
1347                  "or{b} {$src, $dst|$dst, $src}",
1348                  [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1349   def OR16mi   : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
1350                  "or{w} {$src, $dst|$dst, $src}",
1351                  [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1352                  OpSize;
1353   def OR32mi   : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
1354                  "or{l} {$src, $dst|$dst, $src}",
1355                  [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1356   def OR16mi8  : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
1357                  "or{w} {$src, $dst|$dst, $src}",
1358                  [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1359                      OpSize;
1360   def OR32mi8  : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
1361                  "or{l} {$src, $dst|$dst, $src}",
1362                  [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1363 }
1364
1365
1366 let isCommutable = 1 in {   // X = XOR Y, Z   --> X = XOR Z, Y
1367 def XOR8rr   : I<0x30, MRMDestReg,
1368                  (ops R8 :$dst, R8 :$src1, R8 :$src2),
1369                  "xor{b} {$src2, $dst|$dst, $src2}",
1370                  [(set R8:$dst, (xor R8:$src1, R8:$src2))]>;
1371 def XOR16rr  : I<0x31, MRMDestReg, 
1372                  (ops R16:$dst, R16:$src1, R16:$src2), 
1373                  "xor{w} {$src2, $dst|$dst, $src2}",
1374                  [(set R16:$dst, (xor R16:$src1, R16:$src2))]>, OpSize;
1375 def XOR32rr  : I<0x31, MRMDestReg, 
1376                  (ops R32:$dst, R32:$src1, R32:$src2), 
1377                  "xor{l} {$src2, $dst|$dst, $src2}",
1378                  [(set R32:$dst, (xor R32:$src1, R32:$src2))]>;
1379 }
1380
1381 def XOR8rm   : I<0x32, MRMSrcMem , 
1382                  (ops R8 :$dst, R8:$src1, i8mem :$src2), 
1383                  "xor{b} {$src2, $dst|$dst, $src2}",
1384                  [(set R8:$dst, (xor R8:$src1, (load addr:$src2)))]>;
1385 def XOR16rm  : I<0x33, MRMSrcMem , 
1386                  (ops R16:$dst, R16:$src1, i16mem:$src2), 
1387                  "xor{w} {$src2, $dst|$dst, $src2}",
1388                  [(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
1389 def XOR32rm  : I<0x33, MRMSrcMem , 
1390                  (ops R32:$dst, R32:$src1, i32mem:$src2), 
1391                  "xor{l} {$src2, $dst|$dst, $src2}",
1392                  [(set R32:$dst, (xor R32:$src1, (load addr:$src2)))]>;
1393
1394 def XOR8ri   : Ii8<0x80, MRM6r, 
1395                    (ops R8:$dst, R8:$src1, i8imm:$src2), 
1396                    "xor{b} {$src2, $dst|$dst, $src2}",
1397                    [(set R8:$dst, (xor R8:$src1, imm:$src2))]>;
1398 def XOR16ri  : Ii16<0x81, MRM6r, 
1399                     (ops R16:$dst, R16:$src1, i16imm:$src2), 
1400                     "xor{w} {$src2, $dst|$dst, $src2}",
1401                     [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize;
1402 def XOR32ri  : Ii32<0x81, MRM6r, 
1403                     (ops R32:$dst, R32:$src1, i32imm:$src2), 
1404                     "xor{l} {$src2, $dst|$dst, $src2}",
1405                     [(set R32:$dst, (xor R32:$src1, imm:$src2))]>;
1406 def XOR16ri8 : Ii8<0x83, MRM6r, 
1407                    (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1408                    "xor{w} {$src2, $dst|$dst, $src2}",
1409                    [(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
1410                    OpSize;
1411 def XOR32ri8 : Ii8<0x83, MRM6r, 
1412                    (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1413                    "xor{l} {$src2, $dst|$dst, $src2}",
1414                    [(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
1415 let isTwoAddress = 0 in {
1416   def XOR8mr   : I<0x30, MRMDestMem,
1417                    (ops i8mem :$dst, R8 :$src),
1418                    "xor{b} {$src, $dst|$dst, $src}",
1419                    [(store (xor (load addr:$dst), R8:$src), addr:$dst)]>;
1420   def XOR16mr  : I<0x31, MRMDestMem,
1421                    (ops i16mem:$dst, R16:$src),
1422                    "xor{w} {$src, $dst|$dst, $src}",
1423                    [(store (xor (load addr:$dst), R16:$src), addr:$dst)]>,
1424                    OpSize;
1425   def XOR32mr  : I<0x31, MRMDestMem,
1426                    (ops i32mem:$dst, R32:$src),
1427                    "xor{l} {$src, $dst|$dst, $src}",
1428                    [(store (xor (load addr:$dst), R32:$src), addr:$dst)]>;
1429   def XOR8mi   : Ii8<0x80, MRM6m,
1430                      (ops i8mem :$dst, i8imm :$src),
1431                      "xor{b} {$src, $dst|$dst, $src}",
1432                     [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1433   def XOR16mi  : Ii16<0x81, MRM6m,
1434                       (ops i16mem:$dst, i16imm:$src),
1435                       "xor{w} {$src, $dst|$dst, $src}",
1436                    [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1437                       OpSize;
1438   def XOR32mi  : Ii32<0x81, MRM6m,
1439                       (ops i32mem:$dst, i32imm:$src),
1440                       "xor{l} {$src, $dst|$dst, $src}",
1441                    [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1442   def XOR16mi8 : Ii8<0x83, MRM6m,
1443                      (ops i16mem:$dst, i16i8imm :$src),
1444                      "xor{w} {$src, $dst|$dst, $src}",
1445                  [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1446                      OpSize;
1447   def XOR32mi8 : Ii8<0x83, MRM6m,
1448                      (ops i32mem:$dst, i32i8imm :$src),
1449                      "xor{l} {$src, $dst|$dst, $src}",
1450                  [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1451 }
1452
1453 // Shift instructions
1454 def SHL8rCL  : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
1455                  "shl{b} {%cl, $dst|$dst, %CL}",
1456                  [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
1457 def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
1458                  "shl{w} {%cl, $dst|$dst, %CL}",
1459                  [(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1460 def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
1461                  "shl{l} {%cl, $dst|$dst, %CL}",
1462                  [(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
1463
1464 def SHL8ri   : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1465                    "shl{b} {$src2, $dst|$dst, $src2}",
1466                    [(set R8:$dst, (shl R8:$src1, (i8 imm:$src2)))]>;
1467 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1468 def SHL16ri  : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1469                    "shl{w} {$src2, $dst|$dst, $src2}",
1470                    [(set R16:$dst, (shl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1471 def SHL32ri  : Ii8<0xC1, MRM4r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1472                    "shl{l} {$src2, $dst|$dst, $src2}",
1473                    [(set R32:$dst, (shl R32:$src1, (i8 imm:$src2)))]>;
1474 }
1475
1476 let isTwoAddress = 0 in {
1477   def SHL8mCL  : I<0xD2, MRM4m, (ops i8mem :$dst),
1478                    "shl{b} {%cl, $dst|$dst, %CL}",
1479                    [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
1480                    Imp<[CL],[]>;
1481   def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
1482                    "shl{w} {%cl, $dst|$dst, %CL}",
1483                    [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
1484                    Imp<[CL],[]>, OpSize;
1485   def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
1486                    "shl{l} {%cl, $dst|$dst, %CL}",
1487                    [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
1488                    Imp<[CL],[]>;
1489   def SHL8mi   : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
1490                      "shl{b} {$src, $dst|$dst, $src}",
1491                   [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1492   def SHL16mi  : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
1493                      "shl{w} {$src, $dst|$dst, $src}",
1494                  [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1495                      OpSize;
1496   def SHL32mi  : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
1497                      "shl{l} {$src, $dst|$dst, $src}",
1498                  [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1499 }
1500
1501 def SHR8rCL  : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
1502                  "shr{b} {%cl, $dst|$dst, %CL}",
1503                  [(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
1504 def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
1505                  "shr{w} {%cl, $dst|$dst, %CL}",
1506                  [(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1507 def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
1508                  "shr{l} {%cl, $dst|$dst, %CL}",
1509                  [(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
1510
1511 def SHR8ri   : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1512                    "shr{b} {$src2, $dst|$dst, $src2}",
1513                    [(set R8:$dst, (srl R8:$src1, (i8 imm:$src2)))]>;
1514 def SHR16ri  : Ii8<0xC1, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1515                    "shr{w} {$src2, $dst|$dst, $src2}",
1516                    [(set R16:$dst, (srl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1517 def SHR32ri  : Ii8<0xC1, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1518                    "shr{l} {$src2, $dst|$dst, $src2}",
1519                    [(set R32:$dst, (srl R32:$src1, (i8 imm:$src2)))]>;
1520
1521 let isTwoAddress = 0 in {
1522   def SHR8mCL  : I<0xD2, MRM5m, (ops i8mem :$dst),
1523                    "shr{b} {%cl, $dst|$dst, %CL}",
1524                    [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
1525                    Imp<[CL],[]>;
1526   def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
1527                    "shr{w} {%cl, $dst|$dst, %CL}",
1528                    [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
1529                    Imp<[CL],[]>, OpSize;
1530   def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
1531                    "shr{l} {%cl, $dst|$dst, %CL}",
1532                    [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
1533                    Imp<[CL],[]>;
1534   def SHR8mi   : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
1535                      "shr{b} {$src, $dst|$dst, $src}",
1536                   [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1537   def SHR16mi  : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
1538                      "shr{w} {$src, $dst|$dst, $src}",
1539                  [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1540                      OpSize;
1541   def SHR32mi  : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
1542                      "shr{l} {$src, $dst|$dst, $src}",
1543                  [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1544 }
1545
1546 def SAR8rCL  : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
1547                  "sar{b} {%cl, $dst|$dst, %CL}",
1548                  [(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
1549 def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
1550                  "sar{w} {%cl, $dst|$dst, %CL}",
1551                  [(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1552 def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
1553                  "sar{l} {%cl, $dst|$dst, %CL}",
1554                  [(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
1555
1556 def SAR8ri   : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1557                    "sar{b} {$src2, $dst|$dst, $src2}",
1558                    [(set R8:$dst, (sra R8:$src1, (i8 imm:$src2)))]>;
1559 def SAR16ri  : Ii8<0xC1, MRM7r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1560                    "sar{w} {$src2, $dst|$dst, $src2}",
1561                    [(set R16:$dst, (sra R16:$src1, (i8 imm:$src2)))]>,
1562                    OpSize;
1563 def SAR32ri  : Ii8<0xC1, MRM7r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1564                    "sar{l} {$src2, $dst|$dst, $src2}",
1565                    [(set R32:$dst, (sra R32:$src1, (i8 imm:$src2)))]>;
1566 let isTwoAddress = 0 in {
1567   def SAR8mCL  : I<0xD2, MRM7m, (ops i8mem :$dst),
1568                    "sar{b} {%cl, $dst|$dst, %CL}",
1569                    [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
1570                    Imp<[CL],[]>;
1571   def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
1572                    "sar{w} {%cl, $dst|$dst, %CL}",
1573                    [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
1574                    Imp<[CL],[]>, OpSize;
1575   def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst), 
1576                    "sar{l} {%cl, $dst|$dst, %CL}",
1577                    [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
1578                    Imp<[CL],[]>;
1579   def SAR8mi   : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
1580                      "sar{b} {$src, $dst|$dst, $src}",
1581                   [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1582   def SAR16mi  : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
1583                      "sar{w} {$src, $dst|$dst, $src}",
1584                  [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1585                      OpSize;
1586   def SAR32mi  : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
1587                      "sar{l} {$src, $dst|$dst, $src}",
1588                  [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1589 }
1590
1591 // Rotate instructions
1592 // FIXME: provide shorter instructions when imm8 == 1
1593 def ROL8rCL  : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
1594                  "rol{b} {%cl, $dst|$dst, %CL}",
1595                  [(set R8:$dst, (rotl R8:$src, CL))]>, Imp<[CL],[]>;
1596 def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
1597                  "rol{w} {%cl, $dst|$dst, %CL}",
1598                  [(set R16:$dst, (rotl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1599 def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
1600                  "rol{l} {%cl, $dst|$dst, %CL}",
1601                  [(set R32:$dst, (rotl R32:$src, CL))]>, Imp<[CL],[]>;
1602
1603 def ROL8ri   : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1604                    "rol{b} {$src2, $dst|$dst, $src2}",
1605                    [(set R8:$dst, (rotl R8:$src1, (i8 imm:$src2)))]>;
1606 def ROL16ri  : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1607                    "rol{w} {$src2, $dst|$dst, $src2}",
1608                    [(set R16:$dst, (rotl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1609 def ROL32ri  : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1610                    "rol{l} {$src2, $dst|$dst, $src2}",
1611                    [(set R32:$dst, (rotl R32:$src1, (i8 imm:$src2)))]>;
1612
1613 let isTwoAddress = 0 in {
1614   def ROL8mCL  : I<0xD2, MRM0m, (ops i8mem :$dst),
1615                    "rol{b} {%cl, $dst|$dst, %CL}",
1616                    [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>,
1617                    Imp<[CL],[]>;
1618   def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
1619                    "rol{w} {%cl, $dst|$dst, %CL}",
1620                    [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>,
1621                    Imp<[CL],[]>, OpSize;
1622   def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
1623                    "rol{l} {%cl, $dst|$dst, %CL}",
1624                    [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>,
1625                    Imp<[CL],[]>;
1626   def ROL8mi   : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
1627                      "rol{b} {$src, $dst|$dst, $src}",
1628                  [(store (rotl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1629   def ROL16mi  : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
1630                      "rol{w} {$src, $dst|$dst, $src}",
1631                 [(store (rotl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1632                      OpSize;
1633   def ROL32mi  : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
1634                      "rol{l} {$src, $dst|$dst, $src}",
1635                 [(store (rotl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1636 }
1637
1638 def ROR8rCL  : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
1639                  "ror{b} {%cl, $dst|$dst, %CL}",
1640                  [(set R8:$dst, (rotr R8:$src, CL))]>, Imp<[CL],[]>;
1641 def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
1642                  "ror{w} {%cl, $dst|$dst, %CL}",
1643                  [(set R16:$dst, (rotr R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1644 def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
1645                  "ror{l} {%cl, $dst|$dst, %CL}",
1646                  [(set R32:$dst, (rotr R32:$src, CL))]>, Imp<[CL],[]>;
1647
1648 def ROR8ri   : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1649                    "ror{b} {$src2, $dst|$dst, $src2}",
1650                    [(set R8:$dst, (rotr R8:$src1, (i8 imm:$src2)))]>;
1651 def ROR16ri  : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1652                    "ror{w} {$src2, $dst|$dst, $src2}",
1653                    [(set R16:$dst, (rotr R16:$src1, (i8 imm:$src2)))]>, OpSize;
1654 def ROR32ri  : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1655                    "ror{l} {$src2, $dst|$dst, $src2}",
1656                    [(set R32:$dst, (rotr R32:$src1, (i8 imm:$src2)))]>;
1657 let isTwoAddress = 0 in {
1658   def ROR8mCL  : I<0xD2, MRM1m, (ops i8mem :$dst),
1659                    "ror{b} {%cl, $dst|$dst, %CL}",
1660                    [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>,
1661                    Imp<[CL],[]>;
1662   def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
1663                    "ror{w} {%cl, $dst|$dst, %CL}",
1664                    [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>,
1665                    Imp<[CL],[]>, OpSize;
1666   def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst), 
1667                    "ror{l} {%cl, $dst|$dst, %CL}",
1668                    [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>,
1669                    Imp<[CL],[]>;
1670   def ROR8mi   : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
1671                      "ror{b} {$src, $dst|$dst, $src}",
1672                  [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1673   def ROR16mi  : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
1674                      "ror{w} {$src, $dst|$dst, $src}",
1675                 [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1676                      OpSize;
1677   def ROR32mi  : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
1678                      "ror{l} {$src, $dst|$dst, $src}",
1679                 [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1680 }
1681
1682
1683
1684 // Double shift instructions (generalizations of rotate)
1685
1686 def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1687                    "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1688                    [(set R32:$dst, (X86shld R32:$src1, R32:$src2, CL))]>,
1689                    Imp<[CL],[]>, TB;
1690 def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1691                    "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1692                    [(set R32:$dst, (X86shrd R32:$src1, R32:$src2, CL))]>,
1693                    Imp<[CL],[]>, TB;
1694 def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1695                    "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1696                    [(set R16:$dst, (X86shld R16:$src1, R16:$src2, CL))]>,
1697                    Imp<[CL],[]>, TB, OpSize;
1698 def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1699                    "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1700                    [(set R16:$dst, (X86shrd R16:$src1, R16:$src2, CL))]>,
1701                    Imp<[CL],[]>, TB, OpSize;
1702
1703 let isCommutable = 1 in {  // These instructions commute to each other.
1704 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
1705                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1706                      "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1707                      [(set R32:$dst, (X86shld R32:$src1, R32:$src2,
1708                                       (i8 imm:$src3)))]>,
1709                  TB;
1710 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
1711                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1712                      "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1713                      [(set R32:$dst, (X86shrd R32:$src1, R32:$src2,
1714                                       (i8 imm:$src3)))]>,
1715                  TB;
1716 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
1717                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1718                      "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1719                      [(set R16:$dst, (X86shld R16:$src1, R16:$src2,
1720                                       (i8 imm:$src3)))]>,
1721                      TB, OpSize;
1722 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
1723                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1724                      "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1725                      [(set R16:$dst, (X86shrd R16:$src1, R16:$src2,
1726                                       (i8 imm:$src3)))]>,
1727                      TB, OpSize;
1728 }
1729
1730 let isTwoAddress = 0 in {
1731   def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1732                      "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1733                      [(store (X86shld (loadi32 addr:$dst), R32:$src2, CL),
1734                        addr:$dst)]>,
1735                      Imp<[CL],[]>, TB;
1736   def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1737                     "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1738                     [(store (X86shrd (loadi32 addr:$dst), R32:$src2, CL),
1739                       addr:$dst)]>,
1740                     Imp<[CL],[]>, TB;
1741   def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
1742                       (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1743                       "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1744                       [(store (X86shld (loadi32 addr:$dst), R32:$src2,
1745                                         (i8 imm:$src3)), addr:$dst)]>,
1746                       TB;
1747   def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
1748                        (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1749                        "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1750                        [(store (X86shrd (loadi32 addr:$dst), R32:$src2,
1751                                          (i8 imm:$src3)), addr:$dst)]>,
1752                        TB;
1753
1754   def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1755                      "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1756                      [(store (X86shld (loadi16 addr:$dst), R16:$src2, CL),
1757                        addr:$dst)]>,
1758                      Imp<[CL],[]>, TB, OpSize;
1759   def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1760                     "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1761                     [(store (X86shrd (loadi16 addr:$dst), R16:$src2, CL),
1762                       addr:$dst)]>,
1763                     Imp<[CL],[]>, TB, OpSize;
1764   def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
1765                       (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1766                       "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1767                       [(store (X86shld (loadi16 addr:$dst), R16:$src2,
1768                                         (i8 imm:$src3)), addr:$dst)]>,
1769                       TB, OpSize;
1770   def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
1771                        (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1772                        "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1773                       [(store (X86shrd (loadi16 addr:$dst), R16:$src2,
1774                                         (i8 imm:$src3)), addr:$dst)]>,
1775                        TB, OpSize;
1776 }
1777
1778
1779 // Arithmetic.
1780 let isCommutable = 1 in {   // X = ADD Y, Z   --> X = ADD Z, Y
1781 def ADD8rr   : I<0x00, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1782                  "add{b} {$src2, $dst|$dst, $src2}",
1783                  [(set R8:$dst, (add R8:$src1, R8:$src2))]>;
1784 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1785 def ADD16rr  : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1786                  "add{w} {$src2, $dst|$dst, $src2}",
1787                  [(set R16:$dst, (add R16:$src1, R16:$src2))]>, OpSize;
1788 def ADD32rr  : I<0x01, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1789                  "add{l} {$src2, $dst|$dst, $src2}",
1790                  [(set R32:$dst, (add R32:$src1, R32:$src2))]>;
1791 } // end isConvertibleToThreeAddress
1792 } // end isCommutable
1793 def ADD8rm   : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1794                  "add{b} {$src2, $dst|$dst, $src2}",
1795                  [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>;
1796 def ADD16rm  : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1797                  "add{w} {$src2, $dst|$dst, $src2}",
1798                  [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize;
1799 def ADD32rm  : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1800                  "add{l} {$src2, $dst|$dst, $src2}",
1801                  [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>;
1802
1803 def ADD8ri   : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1804                    "add{b} {$src2, $dst|$dst, $src2}",
1805                    [(set R8:$dst, (add R8:$src1, imm:$src2))]>;
1806
1807 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
1808 def ADD16ri  : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1809                     "add{w} {$src2, $dst|$dst, $src2}",
1810                     [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize;
1811 def ADD32ri  : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1812                     "add{l} {$src2, $dst|$dst, $src2}",
1813                     [(set R32:$dst, (add R32:$src1, imm:$src2))]>;
1814 }
1815
1816 // FIXME: move ADD16ri8 above ADD16ri to optimize for space.
1817 def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1818                    "add{w} {$src2, $dst|$dst, $src2}",
1819                    [(set R16:$dst, (add R16:$src1, i16immSExt8:$src2))]>,
1820                    OpSize;
1821 def ADD32ri8 : Ii8<0x83, MRM0r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1822                    "add{l} {$src2, $dst|$dst, $src2}",
1823                    [(set R32:$dst, (add R32:$src1, i32immSExt8:$src2))]>;
1824
1825 let isTwoAddress = 0 in {
1826   def ADD8mr   : I<0x00, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1827                    "add{b} {$src2, $dst|$dst, $src2}",
1828                    [(store (add (load addr:$dst), R8:$src2), addr:$dst)]>;
1829   def ADD16mr  : I<0x01, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1830                    "add{w} {$src2, $dst|$dst, $src2}",
1831                    [(store (add (load addr:$dst), R16:$src2), addr:$dst)]>,
1832                    OpSize;
1833   def ADD32mr  : I<0x01, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1834                    "add{l} {$src2, $dst|$dst, $src2}",
1835                    [(store (add (load addr:$dst), R32:$src2), addr:$dst)]>;
1836   def ADD8mi   : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
1837                      "add{b} {$src2, $dst|$dst, $src2}",
1838                    [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1839   def ADD16mi  : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
1840                       "add{w} {$src2, $dst|$dst, $src2}",
1841                   [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1842                    OpSize;
1843   def ADD32mi  : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
1844                       "add{l} {$src2, $dst|$dst, $src2}",
1845                   [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1846   def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
1847                      "add{w} {$src2, $dst|$dst, $src2}",
1848                 [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1849                    OpSize;
1850   def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
1851                      "add{l} {$src2, $dst|$dst, $src2}",
1852                 [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1853 }
1854
1855 let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
1856 def ADC32rr  : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1857                  "adc{l} {$src2, $dst|$dst, $src2}",
1858                  [(set R32:$dst, (X86adc R32:$src1, R32:$src2))]>;
1859 }
1860 def ADC32rm  : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1861                  "adc{l} {$src2, $dst|$dst, $src2}",
1862                  [(set R32:$dst, (X86adc R32:$src1, (load addr:$src2)))]>;
1863 def ADC32ri  : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1864                     "adc{l} {$src2, $dst|$dst, $src2}",
1865                  [(set R32:$dst, (X86adc R32:$src1, imm:$src2))]>;
1866 def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1867                    "adc{l} {$src2, $dst|$dst, $src2}",
1868                  [(set R32:$dst, (X86adc R32:$src1, i32immSExt8:$src2))]>;
1869
1870 let isTwoAddress = 0 in {
1871   def ADC32mr  : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1872                    "adc{l} {$src2, $dst|$dst, $src2}",
1873                    [(store (X86adc (load addr:$dst), R32:$src2), addr:$dst)]>;
1874   def ADC32mi  : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
1875                       "adc{l} {$src2, $dst|$dst, $src2}",
1876                   [(store (X86adc (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1877   def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
1878                      "adc{l} {$src2, $dst|$dst, $src2}",
1879              [(store (X86adc (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1880 }
1881
1882 def SUB8rr   : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1883                  "sub{b} {$src2, $dst|$dst, $src2}",
1884                  [(set R8:$dst, (sub R8:$src1, R8:$src2))]>;
1885 def SUB16rr  : I<0x29, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1886                  "sub{w} {$src2, $dst|$dst, $src2}",
1887                  [(set R16:$dst, (sub R16:$src1, R16:$src2))]>, OpSize;
1888 def SUB32rr  : I<0x29, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1889                  "sub{l} {$src2, $dst|$dst, $src2}",
1890                  [(set R32:$dst, (sub R32:$src1, R32:$src2))]>;
1891 def SUB8rm   : I<0x2A, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1892                  "sub{b} {$src2, $dst|$dst, $src2}",
1893                  [(set R8:$dst, (sub R8:$src1, (load addr:$src2)))]>;
1894 def SUB16rm  : I<0x2B, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1895                  "sub{w} {$src2, $dst|$dst, $src2}",
1896                  [(set R16:$dst, (sub R16:$src1, (load addr:$src2)))]>, OpSize;
1897 def SUB32rm  : I<0x2B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1898                  "sub{l} {$src2, $dst|$dst, $src2}",
1899                  [(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
1900
1901 def SUB8ri   : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1902                     "sub{b} {$src2, $dst|$dst, $src2}",
1903                     [(set R8:$dst, (sub R8:$src1, imm:$src2))]>;
1904 def SUB16ri  : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1905                     "sub{w} {$src2, $dst|$dst, $src2}",
1906                     [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize;
1907 def SUB32ri  : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1908                     "sub{l} {$src2, $dst|$dst, $src2}",
1909                     [(set R32:$dst, (sub R32:$src1, imm:$src2))]>;
1910 def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1911                    "sub{w} {$src2, $dst|$dst, $src2}",
1912                    [(set R16:$dst, (sub R16:$src1, i16immSExt8:$src2))]>,
1913                    OpSize;
1914 def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1915                    "sub{l} {$src2, $dst|$dst, $src2}",
1916                    [(set R32:$dst, (sub R32:$src1, i32immSExt8:$src2))]>;
1917 let isTwoAddress = 0 in {
1918   def SUB8mr   : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1919                    "sub{b} {$src2, $dst|$dst, $src2}",
1920                    [(store (sub (load addr:$dst), R8:$src2), addr:$dst)]>;
1921   def SUB16mr  : I<0x29, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1922                    "sub{w} {$src2, $dst|$dst, $src2}",
1923                    [(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
1924                    OpSize;
1925   def SUB32mr  : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
1926                    "sub{l} {$src2, $dst|$dst, $src2}",
1927                    [(store (sub (load addr:$dst), R32:$src2), addr:$dst)]>;
1928   def SUB8mi   : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2), 
1929                      "sub{b} {$src2, $dst|$dst, $src2}",
1930                    [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1931   def SUB16mi  : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), 
1932                       "sub{w} {$src2, $dst|$dst, $src2}",
1933                   [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1934                    OpSize;
1935   def SUB32mi  : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), 
1936                       "sub{l} {$src2, $dst|$dst, $src2}",
1937                   [(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1938   def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2), 
1939                      "sub{w} {$src2, $dst|$dst, $src2}",
1940                 [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1941                    OpSize;
1942   def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2), 
1943                      "sub{l} {$src2, $dst|$dst, $src2}",
1944                 [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1945 }
1946
1947 def SBB32rr    : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1948                   "sbb{l} {$src2, $dst|$dst, $src2}",
1949                   [(set R32:$dst, (X86sbb R32:$src1, R32:$src2))]>;
1950
1951 let isTwoAddress = 0 in {
1952   def SBB32mr  : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
1953                    "sbb{l} {$src2, $dst|$dst, $src2}",
1954                    [(store (X86sbb (load addr:$dst), R32:$src2), addr:$dst)]>;
1955   def SBB8mi  : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), 
1956                       "sbb{b} {$src2, $dst|$dst, $src2}",
1957                    [(store (X86sbb (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1958   def SBB16mi  : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), 
1959                       "sbb{w} {$src2, $dst|$dst, $src2}",
1960                   [(store (X86sbb (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1961                      OpSize;
1962   def SBB32mi  : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), 
1963                       "sbb{l} {$src2, $dst|$dst, $src2}",
1964                   [(store (X86sbb (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1965   def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i16i8imm :$src2), 
1966                      "sbb{w} {$src2, $dst|$dst, $src2}",
1967              [(store (X86sbb (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1968                      OpSize;
1969   def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2), 
1970                      "sbb{l} {$src2, $dst|$dst, $src2}",
1971              [(store (X86sbb (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1972 }
1973 def SBB8ri   : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1974                     "sbb{b} {$src2, $dst|$dst, $src2}",
1975                     [(set R8:$dst, (X86sbb R8:$src1, imm:$src2))]>;
1976 def SBB16ri  : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1977                     "sbb{w} {$src2, $dst|$dst, $src2}",
1978                     [(set R16:$dst, (X86sbb R16:$src1, imm:$src2))]>, OpSize;
1979
1980 def SBB32rm  : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1981                     "sbb{l} {$src2, $dst|$dst, $src2}",
1982                     [(set R32:$dst, (X86sbb R32:$src1, (load addr:$src2)))]>;
1983 def SBB32ri  : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1984                     "sbb{l} {$src2, $dst|$dst, $src2}",
1985                     [(set R32:$dst, (X86sbb R32:$src1, imm:$src2))]>;
1986
1987 def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1988                    "sbb{w} {$src2, $dst|$dst, $src2}",
1989                    [(set R16:$dst, (X86sbb R16:$src1, i16immSExt8:$src2))]>,
1990                    OpSize;
1991 def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1992                    "sbb{l} {$src2, $dst|$dst, $src2}",
1993                    [(set R32:$dst, (X86sbb R32:$src1, i32immSExt8:$src2))]>;
1994
1995 let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
1996 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
1997                  "imul{w} {$src2, $dst|$dst, $src2}",
1998                  [(set R16:$dst, (mul R16:$src1, R16:$src2))]>, TB, OpSize;
1999 def IMUL32rr : I<0xAF, MRMSrcReg, (ops R32:$dst, R32:$src1, R32:$src2),
2000                  "imul{l} {$src2, $dst|$dst, $src2}",
2001                  [(set R32:$dst, (mul R32:$src1, R32:$src2))]>, TB;
2002 }
2003 def IMUL16rm : I<0xAF, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
2004                  "imul{w} {$src2, $dst|$dst, $src2}",
2005                  [(set R16:$dst, (mul R16:$src1, (load addr:$src2)))]>,
2006                  TB, OpSize;
2007 def IMUL32rm : I<0xAF, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
2008                  "imul{l} {$src2, $dst|$dst, $src2}",
2009                  [(set R32:$dst, (mul R32:$src1, (load addr:$src2)))]>, TB;
2010
2011 } // end Two Address instructions
2012
2013 // Suprisingly enough, these are not two address instructions!
2014 def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // R16 = R16*I16
2015                       (ops R16:$dst, R16:$src1, i16imm:$src2),
2016                       "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2017                       [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize;
2018 def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // R32 = R32*I32
2019                       (ops R32:$dst, R32:$src1, i32imm:$src2),
2020                       "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2021                       [(set R32:$dst, (mul R32:$src1, imm:$src2))]>;
2022 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // R16 = R16*I8
2023                      (ops R16:$dst, R16:$src1, i16i8imm:$src2),
2024                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2025                      [(set R16:$dst, (mul R16:$src1, i16immSExt8:$src2))]>,
2026                      OpSize;
2027 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // R32 = R32*I8
2028                      (ops R32:$dst, R32:$src1, i32i8imm:$src2),
2029                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2030                      [(set R32:$dst, (mul R32:$src1, i32immSExt8:$src2))]>;
2031
2032 def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                      // R16 = [mem16]*I16
2033                       (ops R16:$dst, i16mem:$src1, i16imm:$src2),
2034                       "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2035                       [(set R16:$dst, (mul (load addr:$src1), imm:$src2))]>,
2036                       OpSize;
2037 def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                      // R32 = [mem32]*I32
2038                       (ops R32:$dst, i32mem:$src1, i32imm:$src2),
2039                       "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2040                       [(set R32:$dst, (mul (load addr:$src1), imm:$src2))]>;
2041 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // R16 = [mem16]*I8
2042                      (ops R16:$dst, i16mem:$src1, i16i8imm :$src2),
2043                      "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2044                   [(set R16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
2045                      OpSize;
2046 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // R32 = [mem32]*I8
2047                      (ops R32:$dst, i32mem:$src1, i32i8imm: $src2),
2048                      "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2049                   [(set R32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
2050
2051 //===----------------------------------------------------------------------===//
2052 // Test instructions are just like AND, except they don't generate a result.
2053 //
2054 let isCommutable = 1 in {   // TEST X, Y   --> TEST Y, X
2055 def TEST8rr  : I<0x84, MRMDestReg, (ops R8:$src1, R8:$src2),
2056                  "test{b} {$src2, $src1|$src1, $src2}",
2057                  [(set STATUS, (X86test R8:$src1, R8:$src2))]>,
2058                Imp<[],[STATUS]>;
2059 def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
2060                  "test{w} {$src2, $src1|$src1, $src2}",
2061                  [(set STATUS, (X86test R16:$src1, R16:$src2))]>,
2062                Imp<[],[STATUS]>, OpSize;
2063 def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
2064                  "test{l} {$src2, $src1|$src1, $src2}",
2065                  [(set STATUS, (X86test R32:$src1, R32:$src2))]>,
2066                Imp<[],[STATUS]>;
2067 }
2068 def TEST8mr  : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
2069                  "test{b} {$src2, $src1|$src1, $src2}",
2070                  [(set STATUS, (X86test (loadi8 addr:$src1), R8:$src2))]>,
2071                Imp<[],[STATUS]>;
2072 def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
2073                  "test{w} {$src2, $src1|$src1, $src2}",
2074                  [(set STATUS, (X86test (loadi16 addr:$src1), R16:$src2))]>,
2075                Imp<[],[STATUS]>, OpSize;
2076 def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
2077                  "test{l} {$src2, $src1|$src1, $src2}",
2078                  [(set STATUS, (X86test (loadi32 addr:$src1), R32:$src2))]>,
2079                Imp<[],[STATUS]>;
2080 def TEST8rm  : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
2081                  "test{b} {$src2, $src1|$src1, $src2}",
2082                  [(set STATUS, (X86test R8:$src1, (loadi8 addr:$src2)))]>,
2083                Imp<[],[STATUS]>;
2084 def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
2085                  "test{w} {$src2, $src1|$src1, $src2}",
2086                  [(set STATUS, (X86test R16:$src1, (loadi16 addr:$src2)))]>,
2087                Imp<[],[STATUS]>, OpSize;
2088 def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
2089                  "test{l} {$src2, $src1|$src1, $src2}",
2090                  [(set STATUS, (X86test R32:$src1, (loadi32 addr:$src2)))]>,
2091                Imp<[],[STATUS]>;
2092
2093 def TEST8ri  : Ii8 <0xF6, MRM0r,                     // flags = R8  & imm8
2094                     (ops R8:$src1, i8imm:$src2),
2095                     "test{b} {$src2, $src1|$src1, $src2}",
2096                     [(set STATUS, (X86test R8:$src1, imm:$src2))]>,
2097                    Imp<[],[STATUS]>;
2098 def TEST16ri : Ii16<0xF7, MRM0r,                     // flags = R16 & imm16
2099                     (ops R16:$src1, i16imm:$src2),
2100                     "test{w} {$src2, $src1|$src1, $src2}",
2101                     [(set STATUS, (X86test R16:$src1, imm:$src2))]>,
2102                    Imp<[],[STATUS]>, OpSize;
2103 def TEST32ri : Ii32<0xF7, MRM0r,                     // flags = R32 & imm32
2104                     (ops R32:$src1, i32imm:$src2),
2105                     "test{l} {$src2, $src1|$src1, $src2}",
2106                     [(set STATUS, (X86test R32:$src1, imm:$src2))]>,
2107                    Imp<[],[STATUS]>;
2108 def TEST8mi  : Ii8 <0xF6, MRM0m,                     // flags = [mem8]  & imm8
2109                     (ops i8mem:$src1, i8imm:$src2),
2110                     "test{b} {$src2, $src1|$src1, $src2}",
2111                     [(set STATUS, (X86test (loadi8 addr:$src1), imm:$src2))]>,
2112                    Imp<[],[STATUS]>;
2113 def TEST16mi : Ii16<0xF7, MRM0m,                     // flags = [mem16] & imm16
2114                     (ops i16mem:$src1, i16imm:$src2),
2115                     "test{w} {$src2, $src1|$src1, $src2}",
2116                     [(set STATUS, (X86test (loadi16 addr:$src1), imm:$src2))]>,
2117                    Imp<[],[STATUS]>, OpSize;
2118 def TEST32mi : Ii32<0xF7, MRM0m,                     // flags = [mem32] & imm32
2119                     (ops i32mem:$src1, i32imm:$src2),
2120                     "test{l} {$src2, $src1|$src1, $src2}",
2121                     [(set STATUS, (X86test (loadi32 addr:$src1), imm:$src2))]>,
2122                    Imp<[],[STATUS]>;
2123
2124
2125 // Condition code ops, incl. set if equal/not equal/...
2126 def SAHF     : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>;  // flags = AH
2127 def LAHF     : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>;  // AH = flags
2128
2129 def SETEr    : I<0x94, MRM0r, 
2130                  (ops R8   :$dst),
2131                  "sete $dst",
2132                  [(set R8:$dst, (X86setcc X86_COND_E, STATUS))]>,
2133                TB;                        // R8 = ==
2134 def SETEm    : I<0x94, MRM0m, 
2135                  (ops i8mem:$dst),
2136                  "sete $dst",
2137                  [(store (X86setcc X86_COND_E, STATUS), addr:$dst)]>,
2138                TB;                        // [mem8] = ==
2139 def SETNEr   : I<0x95, MRM0r, 
2140                  (ops R8   :$dst),
2141                  "setne $dst",
2142                  [(set R8:$dst, (X86setcc X86_COND_NE, STATUS))]>,
2143                TB;                        // R8 = !=
2144 def SETNEm   : I<0x95, MRM0m, 
2145                  (ops i8mem:$dst),
2146                  "setne $dst",
2147                  [(store (X86setcc X86_COND_NE, STATUS), addr:$dst)]>,
2148                TB;                        // [mem8] = !=
2149 def SETLr    : I<0x9C, MRM0r, 
2150                  (ops R8   :$dst),
2151                  "setl $dst",
2152                  [(set R8:$dst, (X86setcc X86_COND_L, STATUS))]>,
2153                TB;                        // R8 = <  signed
2154 def SETLm    : I<0x9C, MRM0m, 
2155                  (ops i8mem:$dst),
2156                  "setl $dst",
2157                  [(store (X86setcc X86_COND_L, STATUS), addr:$dst)]>,
2158                TB;                        // [mem8] = <  signed
2159 def SETGEr   : I<0x9D, MRM0r, 
2160                  (ops R8   :$dst),
2161                  "setge $dst",
2162                  [(set R8:$dst, (X86setcc X86_COND_GE, STATUS))]>,
2163                TB;                        // R8 = >= signed
2164 def SETGEm   : I<0x9D, MRM0m, 
2165                  (ops i8mem:$dst),
2166                  "setge $dst",
2167                  [(store (X86setcc X86_COND_GE, STATUS), addr:$dst)]>,
2168                TB;                        // [mem8] = >= signed
2169 def SETLEr   : I<0x9E, MRM0r, 
2170                  (ops R8   :$dst),
2171                  "setle $dst",
2172                  [(set R8:$dst, (X86setcc X86_COND_LE, STATUS))]>,
2173                TB;                        // R8 = <= signed
2174 def SETLEm   : I<0x9E, MRM0m, 
2175                  (ops i8mem:$dst),
2176                  "setle $dst",
2177                  [(store (X86setcc X86_COND_LE, STATUS), addr:$dst)]>,
2178                TB;                        // [mem8] = <= signed
2179 def SETGr    : I<0x9F, MRM0r, 
2180                  (ops R8   :$dst),
2181                  "setg $dst",
2182                  [(set R8:$dst, (X86setcc X86_COND_G, STATUS))]>,
2183                TB;                        // R8 = >  signed
2184 def SETGm    : I<0x9F, MRM0m, 
2185                  (ops i8mem:$dst),
2186                  "setg $dst",
2187                  [(store (X86setcc X86_COND_G, STATUS), addr:$dst)]>,
2188                TB;                        // [mem8] = >  signed
2189
2190 def SETBr    : I<0x92, MRM0r,
2191                  (ops R8   :$dst),
2192                  "setb $dst",
2193                  [(set R8:$dst, (X86setcc X86_COND_B, STATUS))]>,
2194                TB;                        // R8 = <  unsign
2195 def SETBm    : I<0x92, MRM0m,
2196                  (ops i8mem:$dst),
2197                  "setb $dst",
2198                  [(store (X86setcc X86_COND_B, STATUS), addr:$dst)]>,
2199                TB;                        // [mem8] = <  unsign
2200 def SETAEr   : I<0x93, MRM0r, 
2201                  (ops R8   :$dst),
2202                  "setae $dst",
2203                  [(set R8:$dst, (X86setcc X86_COND_AE, STATUS))]>,
2204                TB;                        // R8 = >= unsign
2205 def SETAEm   : I<0x93, MRM0m, 
2206                  (ops i8mem:$dst),
2207                  "setae $dst",
2208                  [(store (X86setcc X86_COND_AE, STATUS), addr:$dst)]>,
2209                TB;                        // [mem8] = >= unsign
2210 def SETBEr   : I<0x96, MRM0r, 
2211                  (ops R8   :$dst),
2212                  "setbe $dst",
2213                  [(set R8:$dst, (X86setcc X86_COND_BE, STATUS))]>,
2214                TB;                        // R8 = <= unsign
2215 def SETBEm   : I<0x96, MRM0m, 
2216                  (ops i8mem:$dst),
2217                  "setbe $dst",
2218                  [(store (X86setcc X86_COND_BE, STATUS), addr:$dst)]>,
2219                TB;                        // [mem8] = <= unsign
2220 def SETAr    : I<0x97, MRM0r, 
2221                  (ops R8   :$dst),
2222                  "seta $dst",
2223                  [(set R8:$dst, (X86setcc X86_COND_A, STATUS))]>,
2224                TB;                        // R8 = >  signed
2225 def SETAm    : I<0x97, MRM0m, 
2226                  (ops i8mem:$dst),
2227                  "seta $dst",
2228                  [(store (X86setcc X86_COND_A, STATUS), addr:$dst)]>,
2229                TB;                        // [mem8] = >  signed
2230
2231 def SETSr    : I<0x98, MRM0r, 
2232                  (ops R8   :$dst),
2233                  "sets $dst",
2234                  [(set R8:$dst, (X86setcc X86_COND_S, STATUS))]>,
2235                TB;                        // R8 = <sign bit>
2236 def SETSm    : I<0x98, MRM0m, 
2237                  (ops i8mem:$dst),
2238                  "sets $dst",
2239                  [(store (X86setcc X86_COND_S, STATUS), addr:$dst)]>,
2240                TB;                        // [mem8] = <sign bit>
2241 def SETNSr   : I<0x99, MRM0r, 
2242                  (ops R8   :$dst),
2243                  "setns $dst",
2244                  [(set R8:$dst, (X86setcc X86_COND_NS, STATUS))]>,
2245                TB;                        // R8 = !<sign bit>
2246 def SETNSm   : I<0x99, MRM0m, 
2247                  (ops i8mem:$dst),
2248                  "setns $dst",
2249                  [(store (X86setcc X86_COND_NS, STATUS), addr:$dst)]>,
2250                TB;                        // [mem8] = !<sign bit>
2251 def SETPr    : I<0x9A, MRM0r, 
2252                  (ops R8   :$dst),
2253                  "setp $dst",
2254                  [(set R8:$dst, (X86setcc X86_COND_P, STATUS))]>,
2255                TB;                        // R8 = parity
2256 def SETPm    : I<0x9A, MRM0m, 
2257                  (ops i8mem:$dst),
2258                  "setp $dst",
2259                  [(store (X86setcc X86_COND_P, STATUS), addr:$dst)]>,
2260                TB;                        // [mem8] = parity
2261 def SETNPr   : I<0x9B, MRM0r, 
2262                  (ops R8   :$dst),
2263                  "setnp $dst",
2264                  [(set R8:$dst, (X86setcc X86_COND_NP, STATUS))]>,
2265                TB;                        // R8 = not parity
2266 def SETNPm   : I<0x9B, MRM0m, 
2267                  (ops i8mem:$dst),
2268                  "setnp $dst",
2269                  [(store (X86setcc X86_COND_NP, STATUS), addr:$dst)]>,
2270                TB;                        // [mem8] = not parity
2271
2272 // Integer comparisons
2273 def CMP8rr  : I<0x38, MRMDestReg,
2274                 (ops R8 :$src1, R8 :$src2),
2275                 "cmp{b} {$src2, $src1|$src1, $src2}",
2276                 [(set STATUS, (X86cmp R8:$src1, R8:$src2))]>,
2277               Imp<[],[STATUS]>;
2278 def CMP16rr : I<0x39, MRMDestReg,
2279                 (ops R16:$src1, R16:$src2),
2280                 "cmp{w} {$src2, $src1|$src1, $src2}",
2281                 [(set STATUS, (X86cmp R16:$src1, R16:$src2))]>,
2282               Imp<[],[STATUS]>, OpSize;
2283 def CMP32rr : I<0x39, MRMDestReg,
2284                 (ops R32:$src1, R32:$src2),
2285                 "cmp{l} {$src2, $src1|$src1, $src2}",
2286                 [(set STATUS, (X86cmp R32:$src1, R32:$src2))]>,
2287               Imp<[],[STATUS]>;
2288 def CMP8mr  : I<0x38, MRMDestMem,
2289                 (ops i8mem :$src1, R8 :$src2),
2290                 "cmp{b} {$src2, $src1|$src1, $src2}",
2291                 [(set STATUS, (X86cmp (loadi8 addr:$src1), R8:$src2))]>,
2292               Imp<[],[STATUS]>;
2293 def CMP16mr : I<0x39, MRMDestMem,
2294                 (ops i16mem:$src1, R16:$src2),
2295                 "cmp{w} {$src2, $src1|$src1, $src2}",
2296                 [(set STATUS, (X86cmp (loadi16 addr:$src1), R16:$src2))]>,
2297               Imp<[],[STATUS]>, OpSize;
2298 def CMP32mr : I<0x39, MRMDestMem,
2299                 (ops i32mem:$src1, R32:$src2),
2300                 "cmp{l} {$src2, $src1|$src1, $src2}",
2301                 [(set STATUS, (X86cmp (loadi32 addr:$src1), R32:$src2))]>,
2302               Imp<[],[STATUS]>;
2303 def CMP8rm  : I<0x3A, MRMSrcMem,
2304                 (ops R8 :$src1, i8mem :$src2),
2305                 "cmp{b} {$src2, $src1|$src1, $src2}",
2306                 [(set STATUS, (X86cmp R8:$src1, (loadi8 addr:$src2)))]>,
2307               Imp<[],[STATUS]>;
2308 def CMP16rm : I<0x3B, MRMSrcMem,
2309                 (ops R16:$src1, i16mem:$src2),
2310                 "cmp{w} {$src2, $src1|$src1, $src2}",
2311                 [(set STATUS, (X86cmp R16:$src1, (loadi16 addr:$src2)))]>,
2312                 Imp<[],[STATUS]>, OpSize;
2313 def CMP32rm : I<0x3B, MRMSrcMem,
2314                 (ops R32:$src1, i32mem:$src2),
2315                 "cmp{l} {$src2, $src1|$src1, $src2}",
2316                 [(set STATUS, (X86cmp R32:$src1, (loadi32 addr:$src2)))]>,
2317               Imp<[],[STATUS]>;
2318 def CMP8ri  : Ii8<0x80, MRM7r,
2319                   (ops R8:$src1, i8imm:$src2),
2320                   "cmp{b} {$src2, $src1|$src1, $src2}",
2321                   [(set STATUS, (X86cmp R8:$src1, imm:$src2))]>,
2322               Imp<[],[STATUS]>;
2323 def CMP16ri : Ii16<0x81, MRM7r,
2324                    (ops R16:$src1, i16imm:$src2),
2325                    "cmp{w} {$src2, $src1|$src1, $src2}",
2326                    [(set STATUS, (X86cmp R16:$src1, imm:$src2))]>,
2327               Imp<[],[STATUS]>, OpSize;
2328 def CMP32ri : Ii32<0x81, MRM7r,
2329                    (ops R32:$src1, i32imm:$src2),
2330                    "cmp{l} {$src2, $src1|$src1, $src2}",
2331                    [(set STATUS, (X86cmp R32:$src1, imm:$src2))]>,
2332               Imp<[],[STATUS]>;
2333 def CMP8mi  : Ii8 <0x80, MRM7m,
2334                    (ops i8mem :$src1, i8imm :$src2),
2335                    "cmp{b} {$src2, $src1|$src1, $src2}",
2336                    [(set STATUS, (X86cmp (loadi8 addr:$src1), imm:$src2))]>,
2337               Imp<[],[STATUS]>;
2338 def CMP16mi : Ii16<0x81, MRM7m,
2339                    (ops i16mem:$src1, i16imm:$src2),
2340                    "cmp{w} {$src2, $src1|$src1, $src2}",
2341                    [(set STATUS, (X86cmp (loadi16 addr:$src1), imm:$src2))]>,
2342               Imp<[],[STATUS]>, OpSize;
2343 def CMP32mi : Ii32<0x81, MRM7m,
2344                    (ops i32mem:$src1, i32imm:$src2),
2345                    "cmp{l} {$src2, $src1|$src1, $src2}",
2346                    [(set STATUS, (X86cmp (loadi32 addr:$src1), imm:$src2))]>,
2347               Imp<[],[STATUS]>;
2348
2349 // Sign/Zero extenders
2350 def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
2351                    "movs{bw|x} {$src, $dst|$dst, $src}",
2352                    [(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
2353 def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2354                    "movs{bw|x} {$src, $dst|$dst, $src}",
2355                    [(set R16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
2356 def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
2357                    "movs{bl|x} {$src, $dst|$dst, $src}",
2358                    [(set R32:$dst, (sext R8:$src))]>, TB;
2359 def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2360                    "movs{bl|x} {$src, $dst|$dst, $src}",
2361                    [(set R32:$dst, (sextloadi32i8 addr:$src))]>, TB;
2362 def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
2363                    "movs{wl|x} {$src, $dst|$dst, $src}",
2364                    [(set R32:$dst, (sext R16:$src))]>, TB;
2365 def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2366                    "movs{wl|x} {$src, $dst|$dst, $src}",
2367                    [(set R32:$dst, (sextloadi32i16 addr:$src))]>, TB;
2368
2369 def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
2370                    "movz{bw|x} {$src, $dst|$dst, $src}",
2371                    [(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
2372 def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2373                    "movz{bw|x} {$src, $dst|$dst, $src}",
2374                    [(set R16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
2375 def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
2376                    "movz{bl|x} {$src, $dst|$dst, $src}",
2377                    [(set R32:$dst, (zext R8:$src))]>, TB;
2378 def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2379                    "movz{bl|x} {$src, $dst|$dst, $src}",
2380                    [(set R32:$dst, (zextloadi32i8 addr:$src))]>, TB;
2381 def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
2382                    "movz{wl|x} {$src, $dst|$dst, $src}",
2383                    [(set R32:$dst, (zext R16:$src))]>, TB;
2384 def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2385                    "movz{wl|x} {$src, $dst|$dst, $src}",
2386                    [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB;
2387
2388 //===----------------------------------------------------------------------===//
2389 // XMM Floating point support (requires SSE / SSE2)
2390 //===----------------------------------------------------------------------===//
2391
2392 def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2393                 "movss {$src, $dst|$dst, $src}", []>,
2394               Requires<[HasSSE1]>, XS;
2395 def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2396                 "movsd {$src, $dst|$dst, $src}", []>,
2397               Requires<[HasSSE2]>, XD;
2398
2399 def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2400                 "movss {$src, $dst|$dst, $src}",
2401                 [(set FR32:$dst, (loadf32 addr:$src))]>,
2402               Requires<[HasSSE1]>, XS;
2403 def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
2404                 "movss {$src, $dst|$dst, $src}",
2405                 [(store FR32:$src, addr:$dst)]>,
2406               Requires<[HasSSE1]>, XS;
2407 def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2408                 "movsd {$src, $dst|$dst, $src}",
2409                 [(set FR64:$dst, (loadf64 addr:$src))]>,
2410               Requires<[HasSSE2]>, XD;
2411 def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
2412                 "movsd {$src, $dst|$dst, $src}",
2413                 [(store FR64:$src, addr:$dst)]>,
2414               Requires<[HasSSE2]>, XD;
2415
2416 def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
2417                    "cvttsd2si {$src, $dst|$dst, $src}",
2418                    [(set R32:$dst, (fp_to_sint FR64:$src))]>,
2419                  Requires<[HasSSE2]>, XD;
2420 def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
2421                    "cvttsd2si {$src, $dst|$dst, $src}",
2422                    [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
2423                  Requires<[HasSSE2]>, XD;
2424 def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
2425                    "cvttss2si {$src, $dst|$dst, $src}",
2426                    [(set R32:$dst, (fp_to_sint FR32:$src))]>,
2427                  Requires<[HasSSE1]>, XS;
2428 def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
2429                    "cvttss2si {$src, $dst|$dst, $src}",
2430                    [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
2431                  Requires<[HasSSE1]>, XS;
2432 def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
2433                   "cvtsd2ss {$src, $dst|$dst, $src}",
2434                   [(set FR32:$dst, (fround FR64:$src))]>,
2435                 Requires<[HasSSE2]>, XS;
2436 def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), 
2437                   "cvtsd2ss {$src, $dst|$dst, $src}",
2438                   [(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
2439                 Requires<[HasSSE2]>, XS;
2440 def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
2441                   "cvtss2sd {$src, $dst|$dst, $src}",
2442                   [(set FR64:$dst, (fextend FR32:$src))]>,
2443                 Requires<[HasSSE2]>, XD;
2444 def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
2445                   "cvtss2sd {$src, $dst|$dst, $src}",
2446                   [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
2447                 Requires<[HasSSE2]>, XD;
2448 def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
2449                   "cvtsi2ss {$src, $dst|$dst, $src}",
2450                   [(set FR32:$dst, (sint_to_fp R32:$src))]>,
2451                 Requires<[HasSSE2]>, XS;
2452 def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
2453                   "cvtsi2ss {$src, $dst|$dst, $src}",
2454                   [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2455                 Requires<[HasSSE2]>, XS;
2456 def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
2457                   "cvtsi2sd {$src, $dst|$dst, $src}",
2458                   [(set FR64:$dst, (sint_to_fp R32:$src))]>,
2459                 Requires<[HasSSE2]>, XD;
2460 def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
2461                   "cvtsi2sd {$src, $dst|$dst, $src}",
2462                   [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2463                 Requires<[HasSSE2]>, XD;
2464
2465 def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2466                  "sqrtss {$src, $dst|$dst, $src}",
2467                  [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>,
2468                Requires<[HasSSE1]>, XS;
2469 def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2470                  "sqrtss {$src, $dst|$dst, $src}",
2471                  [(set FR32:$dst, (fsqrt FR32:$src))]>,
2472                Requires<[HasSSE1]>, XS;
2473 def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2474                  "sqrtsd {$src, $dst|$dst, $src}",
2475                  [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>,
2476                Requires<[HasSSE2]>, XD;
2477 def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2478                  "sqrtsd {$src, $dst|$dst, $src}",
2479                  [(set FR64:$dst, (fsqrt FR64:$src))]>,
2480                Requires<[HasSSE2]>, XD;
2481
2482 def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2),
2483                  "ucomisd {$src2, $src1|$src1, $src2}",
2484                  [(set STATUS, (X86cmp FR64:$src1, FR64:$src2))]>,
2485                Requires<[HasSSE2]>, TB, OpSize;
2486 def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2),
2487                  "ucomisd {$src2, $src1|$src1, $src2}",
2488                  [(set STATUS, (X86cmp FR64:$src1, (loadf64 addr:$src2)))]>,
2489                Imp<[],[STATUS]>, Requires<[HasSSE2]>, TB, OpSize;
2490 def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2),
2491                  "ucomiss {$src2, $src1|$src1, $src2}",
2492                  [(set STATUS, (X86cmp FR32:$src1, FR32:$src2))]>,
2493                Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB;
2494 def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2),
2495                  "ucomiss {$src2, $src1|$src1, $src2}",
2496                  [(set STATUS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>,
2497                Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB;
2498
2499 // Pseudo-instructions that map fld0 to xorps/xorpd for sse.
2500 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
2501 def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst),
2502                "xorps $dst, $dst", [(set FR32:$dst, fp32imm0)]>,
2503              Requires<[HasSSE1]>, TB;
2504 def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst),
2505                "xorpd $dst, $dst", [(set FR64:$dst, fp64imm0)]>,
2506              Requires<[HasSSE2]>, TB, OpSize;
2507
2508 let isTwoAddress = 1 in {
2509 // SSE Scalar Arithmetic
2510 let isCommutable = 1 in {
2511 def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2512                 "addss {$src2, $dst|$dst, $src2}",
2513                 [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>,
2514               Requires<[HasSSE1]>, XS;
2515 def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2516                 "addsd {$src2, $dst|$dst, $src2}",
2517                 [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>,
2518               Requires<[HasSSE2]>, XD;
2519 def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2520                 "mulss {$src2, $dst|$dst, $src2}",
2521                 [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>,
2522               Requires<[HasSSE1]>, XS;
2523 def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2524                 "mulsd {$src2, $dst|$dst, $src2}",
2525                 [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>,
2526               Requires<[HasSSE2]>, XD;
2527 }
2528
2529 def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2530                 "addss {$src2, $dst|$dst, $src2}",
2531                 [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>,
2532               Requires<[HasSSE1]>, XS;
2533 def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2534                 "addsd {$src2, $dst|$dst, $src2}",
2535                 [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>,
2536               Requires<[HasSSE2]>, XD;
2537 def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2538                 "mulss {$src2, $dst|$dst, $src2}",
2539                 [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>,
2540               Requires<[HasSSE1]>, XS;
2541 def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2542                 "mulsd {$src2, $dst|$dst, $src2}",
2543                 [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>,
2544               Requires<[HasSSE2]>, XD;
2545
2546 def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2547                 "divss {$src2, $dst|$dst, $src2}",
2548                 [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>,
2549               Requires<[HasSSE1]>, XS;
2550 def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2551                 "divss {$src2, $dst|$dst, $src2}",
2552                 [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>,
2553               Requires<[HasSSE1]>, XS;
2554 def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2555                 "divsd {$src2, $dst|$dst, $src2}",
2556                 [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>,
2557               Requires<[HasSSE2]>, XD;
2558 def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2559                 "divsd {$src2, $dst|$dst, $src2}",
2560                 [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>,
2561               Requires<[HasSSE2]>, XD;
2562
2563 def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2564                 "subss {$src2, $dst|$dst, $src2}",
2565                 [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>,
2566               Requires<[HasSSE1]>, XS;
2567 def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2568                 "subss {$src2, $dst|$dst, $src2}",
2569                 [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>,
2570               Requires<[HasSSE1]>, XS;
2571 def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2572                 "subsd {$src2, $dst|$dst, $src2}",
2573                 [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>,
2574               Requires<[HasSSE2]>, XD;
2575 def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2576                 "subsd {$src2, $dst|$dst, $src2}",
2577                 [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>,
2578               Requires<[HasSSE2]>, XD;
2579
2580 // SSE Logical
2581 let isCommutable = 1 in {
2582 def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2583                 "andps {$src2, $dst|$dst, $src2}", []>,
2584               Requires<[HasSSE1]>, TB;
2585 def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2586                 "andpd {$src2, $dst|$dst, $src2}", []>,
2587               Requires<[HasSSE2]>, TB, OpSize;
2588 def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2589                 "orps {$src2, $dst|$dst, $src2}", []>,
2590              Requires<[HasSSE1]>, TB;
2591 def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2592                 "orpd {$src2, $dst|$dst, $src2}", []>,
2593              Requires<[HasSSE2]>, TB, OpSize;
2594 def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2595                 "xorps {$src2, $dst|$dst, $src2}", []>,
2596               Requires<[HasSSE1]>, TB;
2597 def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2598                 "xorpd {$src2, $dst|$dst, $src2}", []>,
2599               Requires<[HasSSE2]>, TB, OpSize;
2600 }
2601 def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2602                 "andnps {$src2, $dst|$dst, $src2}", []>,
2603                Requires<[HasSSE1]>, TB;
2604 def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2605                 "andnpd {$src2, $dst|$dst, $src2}", []>,
2606                Requires<[HasSSE2]>, TB, OpSize;
2607
2608 def CMPSSrr : I<0xC2, MRMSrcReg, 
2609                 (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
2610                 "cmp${cc}ss {$src, $dst|$dst, $src}", []>,
2611               Requires<[HasSSE1]>, XS;
2612 def CMPSSrm : I<0xC2, MRMSrcMem, 
2613                 (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
2614                 "cmp${cc}ss {$src, $dst|$dst, $src}", []>,
2615               Requires<[HasSSE1]>, XS;
2616 def CMPSDrr : I<0xC2, MRMSrcReg, 
2617                 (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
2618                 "cmp${cc}sd {$src, $dst|$dst, $src}", []>,
2619               Requires<[HasSSE1]>, XD;
2620 def CMPSDrm : I<0xC2, MRMSrcMem, 
2621                 (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
2622                 "cmp${cc}sd {$src, $dst|$dst, $src}", []>,
2623               Requires<[HasSSE2]>, XD;
2624 }
2625
2626 //===----------------------------------------------------------------------===//
2627 // Floating Point Stack Support
2628 //===----------------------------------------------------------------------===//
2629
2630 // Floating point support.  All FP Stack operations are represented with two 
2631 // instructions here.  The first instruction, generated by the instruction
2632 // selector, uses "RFP" registers: a traditional register file to reference
2633 // floating point values.  These instructions are all psuedo instructions and
2634 // use the "Fp" prefix.  The second instruction is defined with FPI, which is
2635 // the actual instruction emitted by the assembler.  The FP stackifier pass
2636 // converts one to the other after register allocation occurs.
2637 //
2638 // Note that the FpI instruction should have instruction selection info (e.g.
2639 // a pattern) and the FPI instruction should have emission info (e.g. opcode
2640 // encoding and asm printing info).
2641
2642 // FPI - Floating Point Instruction template.
2643 class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
2644
2645 // FpI_ - Floating Point Psuedo Instruction template. Not Predicated.
2646 class FpI_<dag ops, FPFormat fp, list<dag> pattern>
2647   : X86Inst<0, Pseudo, NoImm, ops, ""> {
2648   let FPForm = fp; let FPFormBits = FPForm.Value;
2649   let Pattern = pattern;
2650 }
2651
2652 // Random Pseudo Instructions.
2653 def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP,
2654                   [(set RFP:$dst, X86fpget)]>;                    // FPR = ST(0)
2655
2656 let noResults = 1 in 
2657   def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP,
2658                         [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;   // ST(0) = FPR
2659
2660 // FpI - Floating Point Psuedo Instruction template. Predicated on FPStack.
2661 class FpI<dag ops, FPFormat fp, list<dag> pattern> :
2662   FpI_<ops, fp, pattern>, Requires<[FPStack]>;
2663
2664
2665 def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
2666
2667 // Arithmetic
2668 // Add, Sub, Mul, Div.
2669 def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2670                 [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
2671 def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2672                 [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>;
2673 def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2674                 [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>;
2675 def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
2676                 [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>;
2677
2678 class FPST0rInst<bits<8> o, string asm>
2679   : FPI<o, AddRegFrm, (ops RST:$op), asm>, D8;
2680 class FPrST0Inst<bits<8> o, string asm>
2681   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DC;
2682 class FPrST0PInst<bits<8> o, string asm>
2683   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DE;
2684
2685 // Binary Ops with a memory source.
2686 def FpADD32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2687                     [(set RFP:$dst, (fadd RFP:$src1,
2688                                      (extloadf64f32 addr:$src2)))]>;
2689                 // ST(0) = ST(0) + [mem32]
2690 def FpADD64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2691                     [(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>;
2692                 // ST(0) = ST(0) + [mem64]
2693 def FpMUL32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2694                     [(set RFP:$dst, (fmul RFP:$src1,
2695                                      (extloadf64f32 addr:$src2)))]>;
2696                 // ST(0) = ST(0) * [mem32]
2697 def FpMUL64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2698                     [(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>;
2699                 // ST(0) = ST(0) * [mem64]
2700 def FpSUB32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2701                     [(set RFP:$dst, (fsub RFP:$src1,
2702                                     (extloadf64f32 addr:$src2)))]>;
2703                 // ST(0) = ST(0) - [mem32]
2704 def FpSUB64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2705                     [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
2706                 // ST(0) = ST(0) - [mem64]
2707 def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2708                     [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2),
2709                                      RFP:$src1))]>;
2710                 // ST(0) = [mem32] - ST(0)
2711 def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2712                     [(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>;
2713                 // ST(0) = [mem64] - ST(0)
2714 def FpDIV32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2715                     [(set RFP:$dst, (fdiv RFP:$src1,
2716                                     (extloadf64f32 addr:$src2)))]>;
2717                 // ST(0) = ST(0) / [mem32]
2718 def FpDIV64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2719                     [(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>;
2720                 // ST(0) = ST(0) / [mem64]
2721 def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
2722                     [(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2),
2723                                      RFP:$src1))]>;
2724                 // ST(0) = [mem32] / ST(0)
2725 def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
2726                     [(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>;
2727                 // ST(0) = [mem64] / ST(0)
2728
2729
2730 def FADD32m  : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
2731 def FADD64m  : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">;
2732 def FMUL32m  : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">;
2733 def FMUL64m  : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">;
2734 def FSUB32m  : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">;
2735 def FSUB64m  : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">;
2736 def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">;
2737 def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">;
2738 def FDIV32m  : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">;
2739 def FDIV64m  : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">;
2740 def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">;
2741 def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
2742
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, i32mem:$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, i32mem:$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, i32mem:$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, i32mem:$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, i32mem:$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, i32mem:$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{l} $src">;
2802 def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">;
2803 def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $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<(zextloadi8i1  addr:$src), (MOV8rm     addr:$src)>;
3034 def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
3035 def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
3036
3037 // extload bool -> extload byte
3038 def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
3039
3040 // anyext -> zext
3041 def : Pat<(i16 (anyext R8 :$src)), (MOVZX16rr8  R8 :$src)>;
3042 def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8  R8 :$src)>;
3043 def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
3044
3045 // Required for RET of f32 / f64 values.
3046 def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>;
3047 def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
3048
3049 // Required for CALL which return f32 / f64 values.
3050 def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>;
3051 def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>;
3052
3053 // Floatin point constant -0.0 and -1.0
3054 def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
3055 def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
3056
3057 // RFP undef
3058 def : Pat<(f64 (undef)), (FpLD0)>,  Requires<[FPStack]>;
3059
3060
3061 //===----------------------------------------------------------------------===//
3062 // Some peepholes
3063 //===----------------------------------------------------------------------===//
3064
3065 // (shl x, 1) ==> (add x, x)
3066 def : Pat<(shl R8 :$src1, (i8 1)), (ADD8rr  R8 :$src1, R8 :$src1)>;
3067 def : Pat<(shl R16:$src1, (i8 1)), (ADD16rr R16:$src1, R16:$src1)>;
3068 def : Pat<(shl R32:$src1, (i8 1)), (ADD32rr R32:$src1, R32:$src1)>;
3069
3070 // (or (x >> c) | (y << (32 - c))) ==> (shrd x, y, c)
3071 def : Pat<(or (srl R32:$src1, CL:$amt),
3072               (shl R32:$src2, (sub 32, CL:$amt))),
3073           (SHRD32rrCL R32:$src1, R32:$src2)>;
3074
3075 // (or (x << c) | (y >> (32 - c))) ==> (shld x, y, c)
3076 def : Pat<(or (shl R32:$src1, CL:$amt),
3077               (srl R32:$src2, (sub 32, CL:$amt))),
3078           (SHLD32rrCL R32:$src1, R32:$src2)>;