1 //===- X86InstrInfo.td - Describe the X86 Instruction Set -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // X86 specific DAG Nodes.
20 def SDTIntShiftDOp: SDTypeProfile<1, 3,
21 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22 SDTCisInt<0>, SDTCisInt<3>]>;
24 def SDTX86CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
26 def SDTX86Cmov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
30 def SDTX86BrCond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>;
33 def SDTX86SetCC : SDTypeProfile<1, 1,
34 [SDTCisVT<0, i8>, SDTCisVT<1, i8>]>;
36 def SDTX86Ret : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
38 def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
39 def SDT_X86CallSeqEnd : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
42 def SDT_X86Call : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
44 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
46 def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
48 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
50 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
51 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
53 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest,
55 def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest,
58 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov,
59 [SDNPInFlag, SDNPOutFlag]>;
60 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
61 [SDNPHasChain, SDNPInFlag]>;
62 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC,
63 [SDNPInFlag, SDNPOutFlag]>;
65 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
66 [SDNPHasChain, SDNPOptInFlag]>;
68 def X86callseq_start :
69 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
72 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
73 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
75 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
76 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
78 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
79 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
80 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
81 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
83 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
84 [SDNPHasChain, SDNPOutFlag]>;
86 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
88 //===----------------------------------------------------------------------===//
89 // X86 Operand Definitions.
92 // *mem - Operand definitions for the funky X86 addressing mode operands.
94 class X86MemOperand<string printMethod> : Operand<i32> {
95 let PrintMethod = printMethod;
96 let NumMIOperands = 4;
97 let MIOperandInfo = (ops R32, i8imm, R32, i32imm);
100 def i8mem : X86MemOperand<"printi8mem">;
101 def i16mem : X86MemOperand<"printi16mem">;
102 def i32mem : X86MemOperand<"printi32mem">;
103 def i64mem : X86MemOperand<"printi64mem">;
104 def i128mem : X86MemOperand<"printi128mem">;
105 def f32mem : X86MemOperand<"printf32mem">;
106 def f64mem : X86MemOperand<"printf64mem">;
107 def f128mem : X86MemOperand<"printf128mem">;
109 def SSECC : Operand<i8> {
110 let PrintMethod = "printSSECC";
113 def piclabel: Operand<i32> {
114 let PrintMethod = "printPICLabel";
117 // A couple of more descriptive operand definitions.
118 // 16-bits but only 8 bits are significant.
119 def i16i8imm : Operand<i16>;
120 // 32-bits but only 8 bits are significant.
121 def i32i8imm : Operand<i32>;
123 // Branch targets have OtherVT type.
124 def brtarget : Operand<OtherVT>;
126 //===----------------------------------------------------------------------===//
127 // X86 Complex Pattern Definitions.
130 // Define X86 specific addressing mode.
131 def addr : ComplexPattern<i32, 4, "SelectAddr", []>;
132 def leaaddr : ComplexPattern<i32, 4, "SelectLEAAddr",
133 [add, mul, shl, frameindex]>;
135 //===----------------------------------------------------------------------===//
136 // X86 Instruction Format Definitions.
139 // Format specifies the encoding used by the instruction. This is part of the
140 // ad-hoc solution used to emit machine instruction encodings by our machine
142 class Format<bits<6> val> {
146 def Pseudo : Format<0>; def RawFrm : Format<1>;
147 def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
148 def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
149 def MRMSrcMem : Format<6>;
150 def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
151 def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
152 def MRM6r : Format<22>; def MRM7r : Format<23>;
153 def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
154 def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
155 def MRM6m : Format<30>; def MRM7m : Format<31>;
156 def MRMInitReg : Format<32>;
158 //===----------------------------------------------------------------------===//
159 // X86 Instruction Predicate Definitions.
160 def HasMMX : Predicate<"Subtarget->hasMMX()">;
161 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
162 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
163 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
164 def FPStack : Predicate<"!Subtarget->hasSSE2()">;
166 //===----------------------------------------------------------------------===//
167 // X86 specific pattern fragments.
170 // ImmType - This specifies the immediate type used by an instruction. This is
171 // part of the ad-hoc solution used to emit machine instruction encodings by our
172 // machine code emitter.
173 class ImmType<bits<2> val> {
176 def NoImm : ImmType<0>;
177 def Imm8 : ImmType<1>;
178 def Imm16 : ImmType<2>;
179 def Imm32 : ImmType<3>;
181 // FPFormat - This specifies what form this FP instruction has. This is used by
182 // the Floating-Point stackifier pass.
183 class FPFormat<bits<3> val> {
186 def NotFP : FPFormat<0>;
187 def ZeroArgFP : FPFormat<1>;
188 def OneArgFP : FPFormat<2>;
189 def OneArgFPRW : FPFormat<3>;
190 def TwoArgFP : FPFormat<4>;
191 def CompareFP : FPFormat<5>;
192 def CondMovFP : FPFormat<6>;
193 def SpecialFP : FPFormat<7>;
196 class X86Inst<bits<8> opcod, Format f, ImmType i, dag ops, string AsmStr>
198 let Namespace = "X86";
200 bits<8> Opcode = opcod;
202 bits<6> FormBits = Form.Value;
204 bits<2> ImmTypeBits = ImmT.Value;
206 dag OperandList = ops;
207 string AsmString = AsmStr;
210 // Attributes specific to X86 instructions...
212 bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix?
214 bits<4> Prefix = 0; // Which prefix byte does this inst have?
215 FPFormat FPForm; // What flavor of FP instruction is this?
216 bits<3> FPFormBits = 0;
219 class Imp<list<Register> uses, list<Register> defs> {
220 list<Register> Uses = uses;
221 list<Register> Defs = defs;
225 // Prefix byte classes which are used to indicate to the ad-hoc machine code
226 // emitter that various prefix bytes are required.
227 class OpSize { bit hasOpSizePrefix = 1; }
228 class TB { bits<4> Prefix = 1; }
229 class REP { bits<4> Prefix = 2; }
230 class D8 { bits<4> Prefix = 3; }
231 class D9 { bits<4> Prefix = 4; }
232 class DA { bits<4> Prefix = 5; }
233 class DB { bits<4> Prefix = 6; }
234 class DC { bits<4> Prefix = 7; }
235 class DD { bits<4> Prefix = 8; }
236 class DE { bits<4> Prefix = 9; }
237 class DF { bits<4> Prefix = 10; }
238 class XD { bits<4> Prefix = 11; }
239 class XS { bits<4> Prefix = 12; }
242 //===----------------------------------------------------------------------===//
243 // Pattern fragments...
246 // X86 specific condition code. These correspond to CondCode in
247 // X86ISelLowering.h. They must be kept in synch.
248 def X86_COND_A : PatLeaf<(i8 0)>;
249 def X86_COND_AE : PatLeaf<(i8 1)>;
250 def X86_COND_B : PatLeaf<(i8 2)>;
251 def X86_COND_BE : PatLeaf<(i8 3)>;
252 def X86_COND_E : PatLeaf<(i8 4)>;
253 def X86_COND_G : PatLeaf<(i8 5)>;
254 def X86_COND_GE : PatLeaf<(i8 6)>;
255 def X86_COND_L : PatLeaf<(i8 7)>;
256 def X86_COND_LE : PatLeaf<(i8 8)>;
257 def X86_COND_NE : PatLeaf<(i8 9)>;
258 def X86_COND_NO : PatLeaf<(i8 10)>;
259 def X86_COND_NP : PatLeaf<(i8 11)>;
260 def X86_COND_NS : PatLeaf<(i8 12)>;
261 def X86_COND_O : PatLeaf<(i8 13)>;
262 def X86_COND_P : PatLeaf<(i8 14)>;
263 def X86_COND_S : PatLeaf<(i8 15)>;
265 def i16immSExt8 : PatLeaf<(i16 imm), [{
266 // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit
267 // sign extended field.
268 return (int)N->getValue() == (signed char)N->getValue();
271 def i32immSExt8 : PatLeaf<(i32 imm), [{
272 // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
273 // sign extended field.
274 return (int)N->getValue() == (signed char)N->getValue();
277 def i16immZExt8 : PatLeaf<(i16 imm), [{
278 // i16immZExt8 predicate - True if the 16-bit immediate fits in a 8-bit zero
280 return (unsigned)N->getValue() == (unsigned char)N->getValue();
283 // Helper fragments for loads.
284 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
285 def loadi16 : PatFrag<(ops node:$ptr), (i16 (load node:$ptr))>;
286 def loadi32 : PatFrag<(ops node:$ptr), (i32 (load node:$ptr))>;
287 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
289 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
290 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
292 def sextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i1))>;
293 def sextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i1))>;
294 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i8))>;
295 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i8))>;
296 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i16))>;
298 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextload node:$ptr, i1))>;
299 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i1))>;
300 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i1))>;
301 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>;
302 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
303 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
305 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>;
307 //===----------------------------------------------------------------------===//
308 // Instruction templates...
310 class I<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
311 : X86Inst<o, f, NoImm, ops, asm> {
312 let Pattern = pattern;
314 class Ii8 <bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
315 : X86Inst<o, f, Imm8 , ops, asm> {
316 let Pattern = pattern;
318 class Ii16<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
319 : X86Inst<o, f, Imm16, ops, asm> {
320 let Pattern = pattern;
322 class Ii32<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
323 : X86Inst<o, f, Imm32, ops, asm> {
324 let Pattern = pattern;
327 //===----------------------------------------------------------------------===//
328 // Instruction list...
331 def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
332 [(X86callseq_start imm:$amt)]>;
333 def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
335 [(X86callseq_end imm:$amt1, imm:$amt2)]>;
336 def IMPLICIT_USE : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
337 def IMPLICIT_DEF : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
338 def IMPLICIT_DEF_R8 : I<0, Pseudo, (ops R8:$dst),
339 "#IMPLICIT_DEF $dst",
340 [(set R8:$dst, (undef))]>;
341 def IMPLICIT_DEF_R16 : I<0, Pseudo, (ops R16:$dst),
342 "#IMPLICIT_DEF $dst",
343 [(set R16:$dst, (undef))]>;
344 def IMPLICIT_DEF_R32 : I<0, Pseudo, (ops R32:$dst),
345 "#IMPLICIT_DEF $dst",
346 [(set R32:$dst, (undef))]>;
349 def NOOP : I<0x90, RawFrm, (ops), "nop", []>;
351 //===----------------------------------------------------------------------===//
352 // Control Flow Instructions...
355 // Return instructions.
356 let isTerminator = 1, isReturn = 1, isBarrier = 1,
357 hasCtrlDep = 1, noResults = 1 in {
358 def RET : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
359 def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
360 [(X86retflag imm:$amt)]>;
363 // All branches are RawFrm, Void, Branch, and Terminators
364 let isBranch = 1, isTerminator = 1, noResults = 1 in
365 class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
366 I<opcode, RawFrm, ops, asm, pattern>;
368 // Conditional branches
370 def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
372 def JE : IBr<0x84, (ops brtarget:$dst), "je $dst",
373 [(X86brcond bb:$dst, X86_COND_E)]>, TB;
374 def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
375 [(X86brcond bb:$dst, X86_COND_NE)]>, TB;
376 def JL : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
377 [(X86brcond bb:$dst, X86_COND_L)]>, TB;
378 def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
379 [(X86brcond bb:$dst, X86_COND_LE)]>, TB;
380 def JG : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
381 [(X86brcond bb:$dst, X86_COND_G)]>, TB;
382 def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
383 [(X86brcond bb:$dst, X86_COND_GE)]>, TB;
385 def JB : IBr<0x82, (ops brtarget:$dst), "jb $dst",
386 [(X86brcond bb:$dst, X86_COND_B)]>, TB;
387 def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
388 [(X86brcond bb:$dst, X86_COND_BE)]>, TB;
389 def JA : IBr<0x87, (ops brtarget:$dst), "ja $dst",
390 [(X86brcond bb:$dst, X86_COND_A)]>, TB;
391 def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
392 [(X86brcond bb:$dst, X86_COND_AE)]>, TB;
394 def JS : IBr<0x88, (ops brtarget:$dst), "js $dst",
395 [(X86brcond bb:$dst, X86_COND_S)]>, TB;
396 def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst",
397 [(X86brcond bb:$dst, X86_COND_NS)]>, TB;
398 def JP : IBr<0x8A, (ops brtarget:$dst), "jp $dst",
399 [(X86brcond bb:$dst, X86_COND_P)]>, TB;
400 def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst",
401 [(X86brcond bb:$dst, X86_COND_NP)]>, TB;
402 def JO : IBr<0x80, (ops brtarget:$dst), "jo $dst",
403 [(X86brcond bb:$dst, X86_COND_O)]>, TB;
404 def JNO : IBr<0x81, (ops brtarget:$dst), "jno $dst",
405 [(X86brcond bb:$dst, X86_COND_NO)]>, TB;
407 //===----------------------------------------------------------------------===//
408 // Call Instructions...
410 let isCall = 1, noResults = 1 in
411 // All calls clobber the non-callee saved registers...
412 let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
413 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
414 def CALLpcrel32 : I<0xE8, RawFrm, (ops i32imm:$dst), "call ${dst:call}",
416 def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst",
417 [(X86call R32:$dst)]>;
418 def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst",
419 [(X86call (loadi32 addr:$dst))]>;
423 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
424 def TAILJMPd : IBr<0xE9, (ops i32imm:$dst), "jmp ${dst:call} # TAIL CALL", []>;
425 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
426 def TAILJMPr : I<0xFF, MRM4r, (ops R32:$dst), "jmp {*}$dst # TAIL CALL", []>;
427 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
428 def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
429 "jmp {*}$dst # TAIL CALL", []>;
431 // ADJSTACKPTRri - This is a standard ADD32ri instruction, identical in every
432 // way, except that it is marked as being a terminator. This causes the epilog
433 // inserter to insert reloads of callee saved registers BEFORE this. We need
434 // this until we have a more accurate way of tracking where the stack pointer is
435 // within a function.
436 let isTerminator = 1, isTwoAddress = 1 in
437 def ADJSTACKPTRri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
438 "add{l} {$src2, $dst|$dst, $src2}", []>;
440 //===----------------------------------------------------------------------===//
441 // Miscellaneous Instructions...
443 def LEAVE : I<0xC9, RawFrm,
444 (ops), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
445 def POP32r : I<0x58, AddRegFrm,
446 (ops R32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
448 def MovePCtoStack : I<0, Pseudo, (ops piclabel:$label),
451 let isTwoAddress = 1 in // R32 = bswap R32
452 def BSWAP32r : I<0xC8, AddRegFrm,
453 (ops R32:$dst, R32:$src),
455 [(set R32:$dst, (bswap R32:$src))]>, TB;
457 def XCHG8rr : I<0x86, MRMDestReg, // xchg R8, R8
458 (ops R8:$src1, R8:$src2),
459 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
460 def XCHG16rr : I<0x87, MRMDestReg, // xchg R16, R16
461 (ops R16:$src1, R16:$src2),
462 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
463 def XCHG32rr : I<0x87, MRMDestReg, // xchg R32, R32
464 (ops R32:$src1, R32:$src2),
465 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
467 def XCHG8mr : I<0x86, MRMDestMem,
468 (ops i8mem:$src1, R8:$src2),
469 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
470 def XCHG16mr : I<0x87, MRMDestMem,
471 (ops i16mem:$src1, R16:$src2),
472 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
473 def XCHG32mr : I<0x87, MRMDestMem,
474 (ops i32mem:$src1, R32:$src2),
475 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
476 def XCHG8rm : I<0x86, MRMSrcMem,
477 (ops R8:$src1, i8mem:$src2),
478 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
479 def XCHG16rm : I<0x87, MRMSrcMem,
480 (ops R16:$src1, i16mem:$src2),
481 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
482 def XCHG32rm : I<0x87, MRMSrcMem,
483 (ops R32:$src1, i32mem:$src2),
484 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
486 def LEA16r : I<0x8D, MRMSrcMem,
487 (ops R16:$dst, i32mem:$src),
488 "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
489 def LEA32r : I<0x8D, MRMSrcMem,
490 (ops R32:$dst, i32mem:$src),
491 "lea{l} {$src|$dst}, {$dst|$src}",
492 [(set R32:$dst, leaaddr:$src)]>;
494 def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}",
496 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
497 def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}",
498 [(X86rep_movs i16)]>,
499 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
500 def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}",
501 [(X86rep_movs i32)]>,
502 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
504 def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}",
506 Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
507 def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}",
508 [(X86rep_stos i16)]>,
509 Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
510 def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
511 [(X86rep_stos i32)]>,
512 Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
515 //===----------------------------------------------------------------------===//
516 // Input/Output Instructions...
518 def IN8rr : I<0xEC, RawFrm, (ops),
519 "in{b} {%dx, %al|%AL, %DX}",
520 []>, Imp<[DX], [AL]>;
521 def IN16rr : I<0xED, RawFrm, (ops),
522 "in{w} {%dx, %ax|%AX, %DX}",
523 []>, Imp<[DX], [AX]>, OpSize;
524 def IN32rr : I<0xED, RawFrm, (ops),
525 "in{l} {%dx, %eax|%EAX, %DX}",
526 []>, Imp<[DX],[EAX]>;
528 def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
529 "in{b} {$port, %al|%AL, $port}",
532 def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
533 "in{w} {$port, %ax|%AX, $port}",
535 Imp<[], [AX]>, OpSize;
536 def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
537 "in{l} {$port, %eax|%EAX, $port}",
541 def OUT8rr : I<0xEE, RawFrm, (ops),
542 "out{b} {%al, %dx|%DX, %AL}",
543 []>, Imp<[DX, AL], []>;
544 def OUT16rr : I<0xEF, RawFrm, (ops),
545 "out{w} {%ax, %dx|%DX, %AX}",
546 []>, Imp<[DX, AX], []>, OpSize;
547 def OUT32rr : I<0xEF, RawFrm, (ops),
548 "out{l} {%eax, %dx|%DX, %EAX}",
549 []>, Imp<[DX, EAX], []>;
551 def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
552 "out{b} {%al, $port|$port, %AL}",
555 def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
556 "out{w} {%ax, $port|$port, %AX}",
558 Imp<[AX], []>, OpSize;
559 def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
560 "out{l} {%eax, $port|$port, %EAX}",
564 //===----------------------------------------------------------------------===//
565 // Move Instructions...
567 def MOV8rr : I<0x88, MRMDestReg, (ops R8 :$dst, R8 :$src),
568 "mov{b} {$src, $dst|$dst, $src}", []>;
569 def MOV16rr : I<0x89, MRMDestReg, (ops R16:$dst, R16:$src),
570 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
571 def MOV32rr : I<0x89, MRMDestReg, (ops R32:$dst, R32:$src),
572 "mov{l} {$src, $dst|$dst, $src}", []>;
573 def MOV8ri : Ii8 <0xB0, AddRegFrm, (ops R8 :$dst, i8imm :$src),
574 "mov{b} {$src, $dst|$dst, $src}",
575 [(set R8:$dst, imm:$src)]>;
576 def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src),
577 "mov{w} {$src, $dst|$dst, $src}",
578 [(set R16:$dst, imm:$src)]>, OpSize;
579 def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src),
580 "mov{l} {$src, $dst|$dst, $src}",
581 [(set R32:$dst, imm:$src)]>;
582 def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
583 "mov{b} {$src, $dst|$dst, $src}",
584 [(store (i8 imm:$src), addr:$dst)]>;
585 def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src),
586 "mov{w} {$src, $dst|$dst, $src}",
587 [(store (i16 imm:$src), addr:$dst)]>, OpSize;
588 def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src),
589 "mov{l} {$src, $dst|$dst, $src}",
590 [(store (i32 imm:$src), addr:$dst)]>;
592 def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src),
593 "mov{b} {$src, $dst|$dst, $src}",
594 [(set R8:$dst, (load addr:$src))]>;
595 def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src),
596 "mov{w} {$src, $dst|$dst, $src}",
597 [(set R16:$dst, (load addr:$src))]>, OpSize;
598 def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src),
599 "mov{l} {$src, $dst|$dst, $src}",
600 [(set R32:$dst, (load addr:$src))]>;
602 def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src),
603 "mov{b} {$src, $dst|$dst, $src}",
604 [(store R8:$src, addr:$dst)]>;
605 def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16:$src),
606 "mov{w} {$src, $dst|$dst, $src}",
607 [(store R16:$src, addr:$dst)]>, OpSize;
608 def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src),
609 "mov{l} {$src, $dst|$dst, $src}",
610 [(store R32:$src, addr:$dst)]>;
612 //===----------------------------------------------------------------------===//
613 // Fixed-Register Multiplication and Division Instructions...
616 // Extra precision multiplication
617 def MUL8r : I<0xF6, MRM4r, (ops R8:$src), "mul{b} $src",
618 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
619 // This probably ought to be moved to a def : Pat<> if the
620 // syntax can be accepted.
621 [(set AL, (mul AL, R8:$src))]>,
622 Imp<[AL],[AX]>; // AL,AH = AL*R8
623 def MUL16r : I<0xF7, MRM4r, (ops R16:$src), "mul{w} $src", []>,
624 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
625 def MUL32r : I<0xF7, MRM4r, (ops R32:$src), "mul{l} $src", []>,
626 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
627 def MUL8m : I<0xF6, MRM4m, (ops i8mem :$src),
629 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
630 // This probably ought to be moved to a def : Pat<> if the
631 // syntax can be accepted.
632 [(set AL, (mul AL, (loadi8 addr:$src)))]>,
633 Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
634 def MUL16m : I<0xF7, MRM4m, (ops i16mem:$src),
635 "mul{w} $src", []>, Imp<[AX],[AX,DX]>,
636 OpSize; // AX,DX = AX*[mem16]
637 def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src),
638 "mul{l} $src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
640 def IMUL8r : I<0xF6, MRM5r, (ops R8:$src), "imul{b} $src", []>,
641 Imp<[AL],[AX]>; // AL,AH = AL*R8
642 def IMUL16r : I<0xF7, MRM5r, (ops R16:$src), "imul{w} $src", []>,
643 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
644 def IMUL32r : I<0xF7, MRM5r, (ops R32:$src), "imul{l} $src", []>,
645 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
646 def IMUL8m : I<0xF6, MRM5m, (ops i8mem :$src),
647 "imul{b} $src", []>, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
648 def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src),
649 "imul{w} $src", []>, Imp<[AX],[AX,DX]>,
650 OpSize; // AX,DX = AX*[mem16]
651 def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src),
653 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
655 // unsigned division/remainder
656 def DIV8r : I<0xF6, MRM6r, (ops R8:$src), // AX/r8 = AL,AH
657 "div{b} $src", []>, Imp<[AX],[AX]>;
658 def DIV16r : I<0xF7, MRM6r, (ops R16:$src), // DX:AX/r16 = AX,DX
659 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
660 def DIV32r : I<0xF7, MRM6r, (ops R32:$src), // EDX:EAX/r32 = EAX,EDX
661 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
662 def DIV8m : I<0xF6, MRM6m, (ops i8mem:$src), // AX/[mem8] = AL,AH
663 "div{b} $src", []>, Imp<[AX],[AX]>;
664 def DIV16m : I<0xF7, MRM6m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
665 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
666 def DIV32m : I<0xF7, MRM6m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
667 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
669 // Signed division/remainder.
670 def IDIV8r : I<0xF6, MRM7r, (ops R8:$src), // AX/r8 = AL,AH
671 "idiv{b} $src", []>, Imp<[AX],[AX]>;
672 def IDIV16r: I<0xF7, MRM7r, (ops R16:$src), // DX:AX/r16 = AX,DX
673 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
674 def IDIV32r: I<0xF7, MRM7r, (ops R32:$src), // EDX:EAX/r32 = EAX,EDX
675 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
676 def IDIV8m : I<0xF6, MRM7m, (ops i8mem:$src), // AX/[mem8] = AL,AH
677 "idiv{b} $src", []>, Imp<[AX],[AX]>;
678 def IDIV16m: I<0xF7, MRM7m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
679 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
680 def IDIV32m: I<0xF7, MRM7m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
681 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
683 // Sign-extenders for division.
684 def CBW : I<0x98, RawFrm, (ops),
685 "{cbtw|cbw}", []>, Imp<[AL],[AH]>; // AX = signext(AL)
686 def CWD : I<0x99, RawFrm, (ops),
687 "{cwtd|cwd}", []>, Imp<[AX],[DX]>; // DX:AX = signext(AX)
688 def CDQ : I<0x99, RawFrm, (ops),
689 "{cltd|cdq}", []>, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
692 //===----------------------------------------------------------------------===//
693 // Two address Instructions...
695 let isTwoAddress = 1 in {
698 def CMOVB16rr : I<0x42, MRMSrcReg, // if <u, R16 = R16
699 (ops R16:$dst, R16:$src1, R16:$src2),
700 "cmovb {$src2, $dst|$dst, $src2}",
701 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
704 def CMOVB16rm : I<0x42, MRMSrcMem, // if <u, R16 = [mem16]
705 (ops R16:$dst, R16:$src1, i16mem:$src2),
706 "cmovb {$src2, $dst|$dst, $src2}",
707 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
710 def CMOVB32rr : I<0x42, MRMSrcReg, // if <u, R32 = R32
711 (ops R32:$dst, R32:$src1, R32:$src2),
712 "cmovb {$src2, $dst|$dst, $src2}",
713 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
716 def CMOVB32rm : I<0x42, MRMSrcMem, // if <u, R32 = [mem32]
717 (ops R32:$dst, R32:$src1, i32mem:$src2),
718 "cmovb {$src2, $dst|$dst, $src2}",
719 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
723 def CMOVAE16rr: I<0x43, MRMSrcReg, // if >=u, R16 = R16
724 (ops R16:$dst, R16:$src1, R16:$src2),
725 "cmovae {$src2, $dst|$dst, $src2}",
726 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
729 def CMOVAE16rm: I<0x43, MRMSrcMem, // if >=u, R16 = [mem16]
730 (ops R16:$dst, R16:$src1, i16mem:$src2),
731 "cmovae {$src2, $dst|$dst, $src2}",
732 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
735 def CMOVAE32rr: I<0x43, MRMSrcReg, // if >=u, R32 = R32
736 (ops R32:$dst, R32:$src1, R32:$src2),
737 "cmovae {$src2, $dst|$dst, $src2}",
738 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
741 def CMOVAE32rm: I<0x43, MRMSrcMem, // if >=u, R32 = [mem32]
742 (ops R32:$dst, R32:$src1, i32mem:$src2),
743 "cmovae {$src2, $dst|$dst, $src2}",
744 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
748 def CMOVE16rr : I<0x44, MRMSrcReg, // if ==, R16 = R16
749 (ops R16:$dst, R16:$src1, R16:$src2),
750 "cmove {$src2, $dst|$dst, $src2}",
751 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
754 def CMOVE16rm : I<0x44, MRMSrcMem, // if ==, R16 = [mem16]
755 (ops R16:$dst, R16:$src1, i16mem:$src2),
756 "cmove {$src2, $dst|$dst, $src2}",
757 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
760 def CMOVE32rr : I<0x44, MRMSrcReg, // if ==, R32 = R32
761 (ops R32:$dst, R32:$src1, R32:$src2),
762 "cmove {$src2, $dst|$dst, $src2}",
763 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
766 def CMOVE32rm : I<0x44, MRMSrcMem, // if ==, R32 = [mem32]
767 (ops R32:$dst, R32:$src1, i32mem:$src2),
768 "cmove {$src2, $dst|$dst, $src2}",
769 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
773 def CMOVNE16rr: I<0x45, MRMSrcReg, // if !=, R16 = R16
774 (ops R16:$dst, R16:$src1, R16:$src2),
775 "cmovne {$src2, $dst|$dst, $src2}",
776 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
779 def CMOVNE16rm: I<0x45, MRMSrcMem, // if !=, R16 = [mem16]
780 (ops R16:$dst, R16:$src1, i16mem:$src2),
781 "cmovne {$src2, $dst|$dst, $src2}",
782 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
785 def CMOVNE32rr: I<0x45, MRMSrcReg, // if !=, R32 = R32
786 (ops R32:$dst, R32:$src1, R32:$src2),
787 "cmovne {$src2, $dst|$dst, $src2}",
788 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
791 def CMOVNE32rm: I<0x45, MRMSrcMem, // if !=, R32 = [mem32]
792 (ops R32:$dst, R32:$src1, i32mem:$src2),
793 "cmovne {$src2, $dst|$dst, $src2}",
794 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
798 def CMOVBE16rr: I<0x46, MRMSrcReg, // if <=u, R16 = R16
799 (ops R16:$dst, R16:$src1, R16:$src2),
800 "cmovbe {$src2, $dst|$dst, $src2}",
801 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
804 def CMOVBE16rm: I<0x46, MRMSrcMem, // if <=u, R16 = [mem16]
805 (ops R16:$dst, R16:$src1, i16mem:$src2),
806 "cmovbe {$src2, $dst|$dst, $src2}",
807 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
810 def CMOVBE32rr: I<0x46, MRMSrcReg, // if <=u, R32 = R32
811 (ops R32:$dst, R32:$src1, R32:$src2),
812 "cmovbe {$src2, $dst|$dst, $src2}",
813 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
816 def CMOVBE32rm: I<0x46, MRMSrcMem, // if <=u, R32 = [mem32]
817 (ops R32:$dst, R32:$src1, i32mem:$src2),
818 "cmovbe {$src2, $dst|$dst, $src2}",
819 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
823 def CMOVA16rr : I<0x47, MRMSrcReg, // if >u, R16 = R16
824 (ops R16:$dst, R16:$src1, R16:$src2),
825 "cmova {$src2, $dst|$dst, $src2}",
826 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
829 def CMOVA16rm : I<0x47, MRMSrcMem, // if >u, R16 = [mem16]
830 (ops R16:$dst, R16:$src1, i16mem:$src2),
831 "cmova {$src2, $dst|$dst, $src2}",
832 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
835 def CMOVA32rr : I<0x47, MRMSrcReg, // if >u, R32 = R32
836 (ops R32:$dst, R32:$src1, R32:$src2),
837 "cmova {$src2, $dst|$dst, $src2}",
838 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
841 def CMOVA32rm : I<0x47, MRMSrcMem, // if >u, R32 = [mem32]
842 (ops R32:$dst, R32:$src1, i32mem:$src2),
843 "cmova {$src2, $dst|$dst, $src2}",
844 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
848 def CMOVL16rr : I<0x4C, MRMSrcReg, // if <s, R16 = R16
849 (ops R16:$dst, R16:$src1, R16:$src2),
850 "cmovl {$src2, $dst|$dst, $src2}",
851 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
854 def CMOVL16rm : I<0x4C, MRMSrcMem, // if <s, R16 = [mem16]
855 (ops R16:$dst, R16:$src1, i16mem:$src2),
856 "cmovl {$src2, $dst|$dst, $src2}",
857 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
860 def CMOVL32rr : I<0x4C, MRMSrcReg, // if <s, R32 = R32
861 (ops R32:$dst, R32:$src1, R32:$src2),
862 "cmovl {$src2, $dst|$dst, $src2}",
863 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
866 def CMOVL32rm : I<0x4C, MRMSrcMem, // if <s, R32 = [mem32]
867 (ops R32:$dst, R32:$src1, i32mem:$src2),
868 "cmovl {$src2, $dst|$dst, $src2}",
869 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
873 def CMOVGE16rr: I<0x4D, MRMSrcReg, // if >=s, R16 = R16
874 (ops R16:$dst, R16:$src1, R16:$src2),
875 "cmovge {$src2, $dst|$dst, $src2}",
876 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
879 def CMOVGE16rm: I<0x4D, MRMSrcMem, // if >=s, R16 = [mem16]
880 (ops R16:$dst, R16:$src1, i16mem:$src2),
881 "cmovge {$src2, $dst|$dst, $src2}",
882 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
885 def CMOVGE32rr: I<0x4D, MRMSrcReg, // if >=s, R32 = R32
886 (ops R32:$dst, R32:$src1, R32:$src2),
887 "cmovge {$src2, $dst|$dst, $src2}",
888 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
891 def CMOVGE32rm: I<0x4D, MRMSrcMem, // if >=s, R32 = [mem32]
892 (ops R32:$dst, R32:$src1, i32mem:$src2),
893 "cmovge {$src2, $dst|$dst, $src2}",
894 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
898 def CMOVLE16rr: I<0x4E, MRMSrcReg, // if <=s, R16 = R16
899 (ops R16:$dst, R16:$src1, R16:$src2),
900 "cmovle {$src2, $dst|$dst, $src2}",
901 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
904 def CMOVLE16rm: I<0x4E, MRMSrcMem, // if <=s, R16 = [mem16]
905 (ops R16:$dst, R16:$src1, i16mem:$src2),
906 "cmovle {$src2, $dst|$dst, $src2}",
907 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
910 def CMOVLE32rr: I<0x4E, MRMSrcReg, // if <=s, R32 = R32
911 (ops R32:$dst, R32:$src1, R32:$src2),
912 "cmovle {$src2, $dst|$dst, $src2}",
913 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
916 def CMOVLE32rm: I<0x4E, MRMSrcMem, // if <=s, R32 = [mem32]
917 (ops R32:$dst, R32:$src1, i32mem:$src2),
918 "cmovle {$src2, $dst|$dst, $src2}",
919 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
923 def CMOVG16rr : I<0x4F, MRMSrcReg, // if >s, R16 = R16
924 (ops R16:$dst, R16:$src1, R16:$src2),
925 "cmovg {$src2, $dst|$dst, $src2}",
926 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
929 def CMOVG16rm : I<0x4F, MRMSrcMem, // if >s, R16 = [mem16]
930 (ops R16:$dst, R16:$src1, i16mem:$src2),
931 "cmovg {$src2, $dst|$dst, $src2}",
932 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
935 def CMOVG32rr : I<0x4F, MRMSrcReg, // if >s, R32 = R32
936 (ops R32:$dst, R32:$src1, R32:$src2),
937 "cmovg {$src2, $dst|$dst, $src2}",
938 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
941 def CMOVG32rm : I<0x4F, MRMSrcMem, // if >s, R32 = [mem32]
942 (ops R32:$dst, R32:$src1, i32mem:$src2),
943 "cmovg {$src2, $dst|$dst, $src2}",
944 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
948 def CMOVS16rr : I<0x48, MRMSrcReg, // if signed, R16 = R16
949 (ops R16:$dst, R16:$src1, R16:$src2),
950 "cmovs {$src2, $dst|$dst, $src2}",
951 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
954 def CMOVS16rm : I<0x48, MRMSrcMem, // if signed, R16 = [mem16]
955 (ops R16:$dst, R16:$src1, i16mem:$src2),
956 "cmovs {$src2, $dst|$dst, $src2}",
957 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
960 def CMOVS32rr : I<0x48, MRMSrcReg, // if signed, R32 = R32
961 (ops R32:$dst, R32:$src1, R32:$src2),
962 "cmovs {$src2, $dst|$dst, $src2}",
963 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
966 def CMOVS32rm : I<0x48, MRMSrcMem, // if signed, R32 = [mem32]
967 (ops R32:$dst, R32:$src1, i32mem:$src2),
968 "cmovs {$src2, $dst|$dst, $src2}",
969 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
973 def CMOVNS16rr: I<0x49, MRMSrcReg, // if !signed, R16 = R16
974 (ops R16:$dst, R16:$src1, R16:$src2),
975 "cmovns {$src2, $dst|$dst, $src2}",
976 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
979 def CMOVNS16rm: I<0x49, MRMSrcMem, // if !signed, R16 = [mem16]
980 (ops R16:$dst, R16:$src1, i16mem:$src2),
981 "cmovns {$src2, $dst|$dst, $src2}",
982 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
985 def CMOVNS32rr: I<0x49, MRMSrcReg, // if !signed, R32 = R32
986 (ops R32:$dst, R32:$src1, R32:$src2),
987 "cmovns {$src2, $dst|$dst, $src2}",
988 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
991 def CMOVNS32rm: I<0x49, MRMSrcMem, // if !signed, R32 = [mem32]
992 (ops R32:$dst, R32:$src1, i32mem:$src2),
993 "cmovns {$src2, $dst|$dst, $src2}",
994 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
998 def CMOVP16rr : I<0x4A, MRMSrcReg, // if parity, R16 = R16
999 (ops R16:$dst, R16:$src1, R16:$src2),
1000 "cmovp {$src2, $dst|$dst, $src2}",
1001 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1004 def CMOVP16rm : I<0x4A, MRMSrcMem, // if parity, R16 = [mem16]
1005 (ops R16:$dst, R16:$src1, i16mem:$src2),
1006 "cmovp {$src2, $dst|$dst, $src2}",
1007 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1010 def CMOVP32rr : I<0x4A, MRMSrcReg, // if parity, R32 = R32
1011 (ops R32:$dst, R32:$src1, R32:$src2),
1012 "cmovp {$src2, $dst|$dst, $src2}",
1013 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1016 def CMOVP32rm : I<0x4A, MRMSrcMem, // if parity, R32 = [mem32]
1017 (ops R32:$dst, R32:$src1, i32mem:$src2),
1018 "cmovp {$src2, $dst|$dst, $src2}",
1019 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1023 def CMOVNP16rr : I<0x4B, MRMSrcReg, // if !parity, R16 = R16
1024 (ops R16:$dst, R16:$src1, R16:$src2),
1025 "cmovnp {$src2, $dst|$dst, $src2}",
1026 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
1029 def CMOVNP16rm : I<0x4B, MRMSrcMem, // if !parity, R16 = [mem16]
1030 (ops R16:$dst, R16:$src1, i16mem:$src2),
1031 "cmovnp {$src2, $dst|$dst, $src2}",
1032 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
1035 def CMOVNP32rr : I<0x4B, MRMSrcReg, // if !parity, R32 = R32
1036 (ops R32:$dst, R32:$src1, R32:$src2),
1037 "cmovnp {$src2, $dst|$dst, $src2}",
1038 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
1041 def CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, R32 = [mem32]
1042 (ops R32:$dst, R32:$src1, i32mem:$src2),
1043 "cmovnp {$src2, $dst|$dst, $src2}",
1044 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
1049 // unary instructions
1050 def NEG8r : I<0xF6, MRM3r, (ops R8 :$dst, R8 :$src), "neg{b} $dst",
1051 [(set R8:$dst, (ineg R8:$src))]>;
1052 def NEG16r : I<0xF7, MRM3r, (ops R16:$dst, R16:$src), "neg{w} $dst",
1053 [(set R16:$dst, (ineg R16:$src))]>, OpSize;
1054 def NEG32r : I<0xF7, MRM3r, (ops R32:$dst, R32:$src), "neg{l} $dst",
1055 [(set R32:$dst, (ineg R32:$src))]>;
1056 let isTwoAddress = 0 in {
1057 def NEG8m : I<0xF6, MRM3m, (ops i8mem :$dst), "neg{b} $dst",
1058 [(store (ineg (loadi8 addr:$dst)), addr:$dst)]>;
1059 def NEG16m : I<0xF7, MRM3m, (ops i16mem:$dst), "neg{w} $dst",
1060 [(store (ineg (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1061 def NEG32m : I<0xF7, MRM3m, (ops i32mem:$dst), "neg{l} $dst",
1062 [(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
1066 def NOT8r : I<0xF6, MRM2r, (ops R8 :$dst, R8 :$src), "not{b} $dst",
1067 [(set R8:$dst, (not R8:$src))]>;
1068 def NOT16r : I<0xF7, MRM2r, (ops R16:$dst, R16:$src), "not{w} $dst",
1069 [(set R16:$dst, (not R16:$src))]>, OpSize;
1070 def NOT32r : I<0xF7, MRM2r, (ops R32:$dst, R32:$src), "not{l} $dst",
1071 [(set R32:$dst, (not R32:$src))]>;
1072 let isTwoAddress = 0 in {
1073 def NOT8m : I<0xF6, MRM2m, (ops i8mem :$dst), "not{b} $dst",
1074 [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
1075 def NOT16m : I<0xF7, MRM2m, (ops i16mem:$dst), "not{w} $dst",
1076 [(store (not (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1077 def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst",
1078 [(store (not (loadi32 addr:$dst)), addr:$dst)]>;
1081 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
1082 def INC8r : I<0xFE, MRM0r, (ops R8 :$dst, R8 :$src), "inc{b} $dst",
1083 [(set R8:$dst, (add R8:$src, 1))]>;
1084 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1085 def INC16r : I<0xFF, MRM0r, (ops R16:$dst, R16:$src), "inc{w} $dst",
1086 [(set R16:$dst, (add R16:$src, 1))]>, OpSize;
1087 def INC32r : I<0xFF, MRM0r, (ops R32:$dst, R32:$src), "inc{l} $dst",
1088 [(set R32:$dst, (add R32:$src, 1))]>;
1090 let isTwoAddress = 0 in {
1091 def INC8m : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
1092 [(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
1093 def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
1094 [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
1095 def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
1096 [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
1099 def DEC8r : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst",
1100 [(set R8:$dst, (add R8:$src, -1))]>;
1101 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1102 def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst",
1103 [(set R16:$dst, (add R16:$src, -1))]>, OpSize;
1104 def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst",
1105 [(set R32:$dst, (add R32:$src, -1))]>;
1108 let isTwoAddress = 0 in {
1109 def DEC8m : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
1110 [(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
1111 def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
1112 [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
1113 def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
1114 [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
1117 // Logical operators...
1118 let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y
1119 def AND8rr : I<0x20, MRMDestReg,
1120 (ops R8 :$dst, R8 :$src1, R8 :$src2),
1121 "and{b} {$src2, $dst|$dst, $src2}",
1122 [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
1123 def AND16rr : I<0x21, MRMDestReg,
1124 (ops R16:$dst, R16:$src1, R16:$src2),
1125 "and{w} {$src2, $dst|$dst, $src2}",
1126 [(set R16:$dst, (and R16:$src1, R16:$src2))]>, OpSize;
1127 def AND32rr : I<0x21, MRMDestReg,
1128 (ops R32:$dst, R32:$src1, R32:$src2),
1129 "and{l} {$src2, $dst|$dst, $src2}",
1130 [(set R32:$dst, (and R32:$src1, R32:$src2))]>;
1133 def AND8rm : I<0x22, MRMSrcMem,
1134 (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1135 "and{b} {$src2, $dst|$dst, $src2}",
1136 [(set R8:$dst, (and R8:$src1, (load addr:$src2)))]>;
1137 def AND16rm : I<0x23, MRMSrcMem,
1138 (ops R16:$dst, R16:$src1, i16mem:$src2),
1139 "and{w} {$src2, $dst|$dst, $src2}",
1140 [(set R16:$dst, (and R16:$src1, (load addr:$src2)))]>, OpSize;
1141 def AND32rm : I<0x23, MRMSrcMem,
1142 (ops R32:$dst, R32:$src1, i32mem:$src2),
1143 "and{l} {$src2, $dst|$dst, $src2}",
1144 [(set R32:$dst, (and R32:$src1, (load addr:$src2)))]>;
1146 def AND8ri : Ii8<0x80, MRM4r,
1147 (ops R8 :$dst, R8 :$src1, i8imm :$src2),
1148 "and{b} {$src2, $dst|$dst, $src2}",
1149 [(set R8:$dst, (and R8:$src1, imm:$src2))]>;
1150 def AND16ri : Ii16<0x81, MRM4r,
1151 (ops R16:$dst, R16:$src1, i16imm:$src2),
1152 "and{w} {$src2, $dst|$dst, $src2}",
1153 [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize;
1154 def AND32ri : Ii32<0x81, MRM4r,
1155 (ops R32:$dst, R32:$src1, i32imm:$src2),
1156 "and{l} {$src2, $dst|$dst, $src2}",
1157 [(set R32:$dst, (and R32:$src1, imm:$src2))]>;
1158 def AND16ri8 : Ii8<0x83, MRM4r,
1159 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1160 "and{w} {$src2, $dst|$dst, $src2}",
1161 [(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
1163 def AND32ri8 : Ii8<0x83, MRM4r,
1164 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1165 "and{l} {$src2, $dst|$dst, $src2}",
1166 [(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
1168 let isTwoAddress = 0 in {
1169 def AND8mr : I<0x20, MRMDestMem,
1170 (ops i8mem :$dst, R8 :$src),
1171 "and{b} {$src, $dst|$dst, $src}",
1172 [(store (and (load addr:$dst), R8:$src), addr:$dst)]>;
1173 def AND16mr : I<0x21, MRMDestMem,
1174 (ops i16mem:$dst, R16:$src),
1175 "and{w} {$src, $dst|$dst, $src}",
1176 [(store (and (load addr:$dst), R16:$src), addr:$dst)]>,
1178 def AND32mr : I<0x21, MRMDestMem,
1179 (ops i32mem:$dst, R32:$src),
1180 "and{l} {$src, $dst|$dst, $src}",
1181 [(store (and (load addr:$dst), R32:$src), addr:$dst)]>;
1182 def AND8mi : Ii8<0x80, MRM4m,
1183 (ops i8mem :$dst, i8imm :$src),
1184 "and{b} {$src, $dst|$dst, $src}",
1185 [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1186 def AND16mi : Ii16<0x81, MRM4m,
1187 (ops i16mem:$dst, i16imm:$src),
1188 "and{w} {$src, $dst|$dst, $src}",
1189 [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1191 def AND32mi : Ii32<0x81, MRM4m,
1192 (ops i32mem:$dst, i32imm:$src),
1193 "and{l} {$src, $dst|$dst, $src}",
1194 [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1195 def AND16mi8 : Ii8<0x83, MRM4m,
1196 (ops i16mem:$dst, i16i8imm :$src),
1197 "and{w} {$src, $dst|$dst, $src}",
1198 [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1200 def AND32mi8 : Ii8<0x83, MRM4m,
1201 (ops i32mem:$dst, i32i8imm :$src),
1202 "and{l} {$src, $dst|$dst, $src}",
1203 [(store (and (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1207 let isCommutable = 1 in { // X = OR Y, Z --> X = OR Z, Y
1208 def OR8rr : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1209 "or{b} {$src2, $dst|$dst, $src2}",
1210 [(set R8:$dst, (or R8:$src1, R8:$src2))]>;
1211 def OR16rr : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1212 "or{w} {$src2, $dst|$dst, $src2}",
1213 [(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
1214 def OR32rr : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1215 "or{l} {$src2, $dst|$dst, $src2}",
1216 [(set R32:$dst, (or R32:$src1, R32:$src2))]>;
1218 def OR8rm : I<0x0A, MRMSrcMem , (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1219 "or{b} {$src2, $dst|$dst, $src2}",
1220 [(set R8:$dst, (or R8:$src1, (load addr:$src2)))]>;
1221 def OR16rm : I<0x0B, MRMSrcMem , (ops R16:$dst, R16:$src1, i16mem:$src2),
1222 "or{w} {$src2, $dst|$dst, $src2}",
1223 [(set R16:$dst, (or R16:$src1, (load addr:$src2)))]>, OpSize;
1224 def OR32rm : I<0x0B, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1225 "or{l} {$src2, $dst|$dst, $src2}",
1226 [(set R32:$dst, (or R32:$src1, (load addr:$src2)))]>;
1228 def OR8ri : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1229 "or{b} {$src2, $dst|$dst, $src2}",
1230 [(set R8:$dst, (or R8:$src1, imm:$src2))]>;
1231 def OR16ri : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1232 "or{w} {$src2, $dst|$dst, $src2}",
1233 [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize;
1234 def OR32ri : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1235 "or{l} {$src2, $dst|$dst, $src2}",
1236 [(set R32:$dst, (or R32:$src1, imm:$src2))]>;
1238 def OR16ri8 : Ii8<0x83, MRM1r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1239 "or{w} {$src2, $dst|$dst, $src2}",
1240 [(set R16:$dst, (or R16:$src1, i16immSExt8:$src2))]>, OpSize;
1241 def OR32ri8 : Ii8<0x83, MRM1r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1242 "or{l} {$src2, $dst|$dst, $src2}",
1243 [(set R32:$dst, (or R32:$src1, i32immSExt8:$src2))]>;
1244 let isTwoAddress = 0 in {
1245 def OR8mr : I<0x08, MRMDestMem, (ops i8mem:$dst, R8:$src),
1246 "or{b} {$src, $dst|$dst, $src}",
1247 [(store (or (load addr:$dst), R8:$src), addr:$dst)]>;
1248 def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, R16:$src),
1249 "or{w} {$src, $dst|$dst, $src}",
1250 [(store (or (load addr:$dst), R16:$src), addr:$dst)]>, OpSize;
1251 def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, R32:$src),
1252 "or{l} {$src, $dst|$dst, $src}",
1253 [(store (or (load addr:$dst), R32:$src), addr:$dst)]>;
1254 def OR8mi : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
1255 "or{b} {$src, $dst|$dst, $src}",
1256 [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1257 def OR16mi : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
1258 "or{w} {$src, $dst|$dst, $src}",
1259 [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1261 def OR32mi : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
1262 "or{l} {$src, $dst|$dst, $src}",
1263 [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1264 def OR16mi8 : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
1265 "or{w} {$src, $dst|$dst, $src}",
1266 [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1268 def OR32mi8 : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
1269 "or{l} {$src, $dst|$dst, $src}",
1270 [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1274 let isCommutable = 1 in { // X = XOR Y, Z --> X = XOR Z, Y
1275 def XOR8rr : I<0x30, MRMDestReg,
1276 (ops R8 :$dst, R8 :$src1, R8 :$src2),
1277 "xor{b} {$src2, $dst|$dst, $src2}",
1278 [(set R8:$dst, (xor R8:$src1, R8:$src2))]>;
1279 def XOR16rr : I<0x31, MRMDestReg,
1280 (ops R16:$dst, R16:$src1, R16:$src2),
1281 "xor{w} {$src2, $dst|$dst, $src2}",
1282 [(set R16:$dst, (xor R16:$src1, R16:$src2))]>, OpSize;
1283 def XOR32rr : I<0x31, MRMDestReg,
1284 (ops R32:$dst, R32:$src1, R32:$src2),
1285 "xor{l} {$src2, $dst|$dst, $src2}",
1286 [(set R32:$dst, (xor R32:$src1, R32:$src2))]>;
1289 def XOR8rm : I<0x32, MRMSrcMem ,
1290 (ops R8 :$dst, R8:$src1, i8mem :$src2),
1291 "xor{b} {$src2, $dst|$dst, $src2}",
1292 [(set R8:$dst, (xor R8:$src1, (load addr:$src2)))]>;
1293 def XOR16rm : I<0x33, MRMSrcMem ,
1294 (ops R16:$dst, R16:$src1, i16mem:$src2),
1295 "xor{w} {$src2, $dst|$dst, $src2}",
1296 [(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
1297 def XOR32rm : I<0x33, MRMSrcMem ,
1298 (ops R32:$dst, R32:$src1, i32mem:$src2),
1299 "xor{l} {$src2, $dst|$dst, $src2}",
1300 [(set R32:$dst, (xor R32:$src1, (load addr:$src2)))]>;
1302 def XOR8ri : Ii8<0x80, MRM6r,
1303 (ops R8:$dst, R8:$src1, i8imm:$src2),
1304 "xor{b} {$src2, $dst|$dst, $src2}",
1305 [(set R8:$dst, (xor R8:$src1, imm:$src2))]>;
1306 def XOR16ri : Ii16<0x81, MRM6r,
1307 (ops R16:$dst, R16:$src1, i16imm:$src2),
1308 "xor{w} {$src2, $dst|$dst, $src2}",
1309 [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize;
1310 def XOR32ri : Ii32<0x81, MRM6r,
1311 (ops R32:$dst, R32:$src1, i32imm:$src2),
1312 "xor{l} {$src2, $dst|$dst, $src2}",
1313 [(set R32:$dst, (xor R32:$src1, imm:$src2))]>;
1314 def XOR16ri8 : Ii8<0x83, MRM6r,
1315 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1316 "xor{w} {$src2, $dst|$dst, $src2}",
1317 [(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
1319 def XOR32ri8 : Ii8<0x83, MRM6r,
1320 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1321 "xor{l} {$src2, $dst|$dst, $src2}",
1322 [(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
1323 let isTwoAddress = 0 in {
1324 def XOR8mr : I<0x30, MRMDestMem,
1325 (ops i8mem :$dst, R8 :$src),
1326 "xor{b} {$src, $dst|$dst, $src}",
1327 [(store (xor (load addr:$dst), R8:$src), addr:$dst)]>;
1328 def XOR16mr : I<0x31, MRMDestMem,
1329 (ops i16mem:$dst, R16:$src),
1330 "xor{w} {$src, $dst|$dst, $src}",
1331 [(store (xor (load addr:$dst), R16:$src), addr:$dst)]>,
1333 def XOR32mr : I<0x31, MRMDestMem,
1334 (ops i32mem:$dst, R32:$src),
1335 "xor{l} {$src, $dst|$dst, $src}",
1336 [(store (xor (load addr:$dst), R32:$src), addr:$dst)]>;
1337 def XOR8mi : Ii8<0x80, MRM6m,
1338 (ops i8mem :$dst, i8imm :$src),
1339 "xor{b} {$src, $dst|$dst, $src}",
1340 [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1341 def XOR16mi : Ii16<0x81, MRM6m,
1342 (ops i16mem:$dst, i16imm:$src),
1343 "xor{w} {$src, $dst|$dst, $src}",
1344 [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1346 def XOR32mi : Ii32<0x81, MRM6m,
1347 (ops i32mem:$dst, i32imm:$src),
1348 "xor{l} {$src, $dst|$dst, $src}",
1349 [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1350 def XOR16mi8 : Ii8<0x83, MRM6m,
1351 (ops i16mem:$dst, i16i8imm :$src),
1352 "xor{w} {$src, $dst|$dst, $src}",
1353 [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1355 def XOR32mi8 : Ii8<0x83, MRM6m,
1356 (ops i32mem:$dst, i32i8imm :$src),
1357 "xor{l} {$src, $dst|$dst, $src}",
1358 [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1361 // Shift instructions
1362 def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
1363 "shl{b} {%cl, $dst|$dst, %CL}",
1364 [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
1365 def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
1366 "shl{w} {%cl, $dst|$dst, %CL}",
1367 [(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1368 def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
1369 "shl{l} {%cl, $dst|$dst, %CL}",
1370 [(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
1372 def SHL8ri : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1373 "shl{b} {$src2, $dst|$dst, $src2}",
1374 [(set R8:$dst, (shl R8:$src1, (i8 imm:$src2)))]>;
1375 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1376 def SHL16ri : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1377 "shl{w} {$src2, $dst|$dst, $src2}",
1378 [(set R16:$dst, (shl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1379 def SHL32ri : Ii8<0xC1, MRM4r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1380 "shl{l} {$src2, $dst|$dst, $src2}",
1381 [(set R32:$dst, (shl R32:$src1, (i8 imm:$src2)))]>;
1384 let isTwoAddress = 0 in {
1385 def SHL8mCL : I<0xD2, MRM4m, (ops i8mem :$dst),
1386 "shl{b} {%cl, $dst|$dst, %CL}",
1387 [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
1389 def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
1390 "shl{w} {%cl, $dst|$dst, %CL}",
1391 [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
1392 Imp<[CL],[]>, OpSize;
1393 def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
1394 "shl{l} {%cl, $dst|$dst, %CL}",
1395 [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
1397 def SHL8mi : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
1398 "shl{b} {$src, $dst|$dst, $src}",
1399 [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1400 def SHL16mi : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
1401 "shl{w} {$src, $dst|$dst, $src}",
1402 [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1404 def SHL32mi : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
1405 "shl{l} {$src, $dst|$dst, $src}",
1406 [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1409 def SHR8rCL : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
1410 "shr{b} {%cl, $dst|$dst, %CL}",
1411 [(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
1412 def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
1413 "shr{w} {%cl, $dst|$dst, %CL}",
1414 [(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1415 def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
1416 "shr{l} {%cl, $dst|$dst, %CL}",
1417 [(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
1419 def SHR8ri : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1420 "shr{b} {$src2, $dst|$dst, $src2}",
1421 [(set R8:$dst, (srl R8:$src1, (i8 imm:$src2)))]>;
1422 def SHR16ri : Ii8<0xC1, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1423 "shr{w} {$src2, $dst|$dst, $src2}",
1424 [(set R16:$dst, (srl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1425 def SHR32ri : Ii8<0xC1, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1426 "shr{l} {$src2, $dst|$dst, $src2}",
1427 [(set R32:$dst, (srl R32:$src1, (i8 imm:$src2)))]>;
1429 let isTwoAddress = 0 in {
1430 def SHR8mCL : I<0xD2, MRM5m, (ops i8mem :$dst),
1431 "shr{b} {%cl, $dst|$dst, %CL}",
1432 [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
1434 def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
1435 "shr{w} {%cl, $dst|$dst, %CL}",
1436 [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
1437 Imp<[CL],[]>, OpSize;
1438 def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
1439 "shr{l} {%cl, $dst|$dst, %CL}",
1440 [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
1442 def SHR8mi : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
1443 "shr{b} {$src, $dst|$dst, $src}",
1444 [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1445 def SHR16mi : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
1446 "shr{w} {$src, $dst|$dst, $src}",
1447 [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1449 def SHR32mi : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
1450 "shr{l} {$src, $dst|$dst, $src}",
1451 [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1454 def SAR8rCL : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
1455 "sar{b} {%cl, $dst|$dst, %CL}",
1456 [(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
1457 def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
1458 "sar{w} {%cl, $dst|$dst, %CL}",
1459 [(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1460 def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
1461 "sar{l} {%cl, $dst|$dst, %CL}",
1462 [(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
1464 def SAR8ri : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1465 "sar{b} {$src2, $dst|$dst, $src2}",
1466 [(set R8:$dst, (sra R8:$src1, (i8 imm:$src2)))]>;
1467 def SAR16ri : Ii8<0xC1, MRM7r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1468 "sar{w} {$src2, $dst|$dst, $src2}",
1469 [(set R16:$dst, (sra R16:$src1, (i8 imm:$src2)))]>,
1471 def SAR32ri : Ii8<0xC1, MRM7r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1472 "sar{l} {$src2, $dst|$dst, $src2}",
1473 [(set R32:$dst, (sra R32:$src1, (i8 imm:$src2)))]>;
1474 let isTwoAddress = 0 in {
1475 def SAR8mCL : I<0xD2, MRM7m, (ops i8mem :$dst),
1476 "sar{b} {%cl, $dst|$dst, %CL}",
1477 [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
1479 def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
1480 "sar{w} {%cl, $dst|$dst, %CL}",
1481 [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
1482 Imp<[CL],[]>, OpSize;
1483 def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst),
1484 "sar{l} {%cl, $dst|$dst, %CL}",
1485 [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
1487 def SAR8mi : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
1488 "sar{b} {$src, $dst|$dst, $src}",
1489 [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1490 def SAR16mi : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
1491 "sar{w} {$src, $dst|$dst, $src}",
1492 [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1494 def SAR32mi : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
1495 "sar{l} {$src, $dst|$dst, $src}",
1496 [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1499 // Rotate instructions
1500 // FIXME: provide shorter instructions when imm8 == 1
1501 def ROL8rCL : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
1502 "rol{b} {%cl, $dst|$dst, %CL}",
1503 [(set R8:$dst, (rotl R8:$src, CL))]>, Imp<[CL],[]>;
1504 def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
1505 "rol{w} {%cl, $dst|$dst, %CL}",
1506 [(set R16:$dst, (rotl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1507 def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
1508 "rol{l} {%cl, $dst|$dst, %CL}",
1509 [(set R32:$dst, (rotl R32:$src, CL))]>, Imp<[CL],[]>;
1511 def ROL8ri : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1512 "rol{b} {$src2, $dst|$dst, $src2}",
1513 [(set R8:$dst, (rotl R8:$src1, (i8 imm:$src2)))]>;
1514 def ROL16ri : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1515 "rol{w} {$src2, $dst|$dst, $src2}",
1516 [(set R16:$dst, (rotl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1517 def ROL32ri : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1518 "rol{l} {$src2, $dst|$dst, $src2}",
1519 [(set R32:$dst, (rotl R32:$src1, (i8 imm:$src2)))]>;
1521 let isTwoAddress = 0 in {
1522 def ROL8mCL : I<0xD2, MRM0m, (ops i8mem :$dst),
1523 "rol{b} {%cl, $dst|$dst, %CL}",
1524 [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>,
1526 def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
1527 "rol{w} {%cl, $dst|$dst, %CL}",
1528 [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>,
1529 Imp<[CL],[]>, OpSize;
1530 def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
1531 "rol{l} {%cl, $dst|$dst, %CL}",
1532 [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>,
1534 def ROL8mi : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
1535 "rol{b} {$src, $dst|$dst, $src}",
1536 [(store (rotl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1537 def ROL16mi : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
1538 "rol{w} {$src, $dst|$dst, $src}",
1539 [(store (rotl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1541 def ROL32mi : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
1542 "rol{l} {$src, $dst|$dst, $src}",
1543 [(store (rotl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1546 def ROR8rCL : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
1547 "ror{b} {%cl, $dst|$dst, %CL}",
1548 [(set R8:$dst, (rotr R8:$src, CL))]>, Imp<[CL],[]>;
1549 def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
1550 "ror{w} {%cl, $dst|$dst, %CL}",
1551 [(set R16:$dst, (rotr R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1552 def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
1553 "ror{l} {%cl, $dst|$dst, %CL}",
1554 [(set R32:$dst, (rotr R32:$src, CL))]>, Imp<[CL],[]>;
1556 def ROR8ri : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1557 "ror{b} {$src2, $dst|$dst, $src2}",
1558 [(set R8:$dst, (rotr R8:$src1, (i8 imm:$src2)))]>;
1559 def ROR16ri : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1560 "ror{w} {$src2, $dst|$dst, $src2}",
1561 [(set R16:$dst, (rotr R16:$src1, (i8 imm:$src2)))]>, OpSize;
1562 def ROR32ri : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1563 "ror{l} {$src2, $dst|$dst, $src2}",
1564 [(set R32:$dst, (rotr R32:$src1, (i8 imm:$src2)))]>;
1565 let isTwoAddress = 0 in {
1566 def ROR8mCL : I<0xD2, MRM1m, (ops i8mem :$dst),
1567 "ror{b} {%cl, $dst|$dst, %CL}",
1568 [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>,
1570 def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
1571 "ror{w} {%cl, $dst|$dst, %CL}",
1572 [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>,
1573 Imp<[CL],[]>, OpSize;
1574 def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst),
1575 "ror{l} {%cl, $dst|$dst, %CL}",
1576 [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>,
1578 def ROR8mi : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
1579 "ror{b} {$src, $dst|$dst, $src}",
1580 [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1581 def ROR16mi : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
1582 "ror{w} {$src, $dst|$dst, $src}",
1583 [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1585 def ROR32mi : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
1586 "ror{l} {$src, $dst|$dst, $src}",
1587 [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1592 // Double shift instructions (generalizations of rotate)
1593 def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1594 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1595 [(set R32:$dst, (X86shld R32:$src1, R32:$src2, CL))]>,
1597 def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1598 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1599 [(set R32:$dst, (X86shrd R32:$src1, R32:$src2, CL))]>,
1601 def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1602 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1603 [(set R16:$dst, (X86shld R16:$src1, R16:$src2, CL))]>,
1604 Imp<[CL],[]>, TB, OpSize;
1605 def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1606 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1607 [(set R16:$dst, (X86shrd R16:$src1, R16:$src2, CL))]>,
1608 Imp<[CL],[]>, TB, OpSize;
1610 let isCommutable = 1 in { // These instructions commute to each other.
1611 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
1612 (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1613 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1614 [(set R32:$dst, (X86shld R32:$src1, R32:$src2,
1617 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
1618 (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1619 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1620 [(set R32:$dst, (X86shrd R32:$src1, R32:$src2,
1623 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
1624 (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1625 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1626 [(set R16:$dst, (X86shld R16:$src1, R16:$src2,
1629 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
1630 (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1631 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1632 [(set R16:$dst, (X86shrd R16:$src1, R16:$src2,
1637 let isTwoAddress = 0 in {
1638 def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1639 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1640 [(store (X86shld (loadi32 addr:$dst), R32:$src2, CL),
1643 def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1644 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1645 [(store (X86shrd (loadi32 addr:$dst), R32:$src2, CL),
1648 def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
1649 (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1650 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1651 [(store (X86shld (loadi32 addr:$dst), R32:$src2,
1652 (i8 imm:$src3)), addr:$dst)]>,
1654 def SHRD32mri8 : Ii8<0xAC, MRMDestMem,
1655 (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1656 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1657 [(store (X86shrd (loadi32 addr:$dst), R32:$src2,
1658 (i8 imm:$src3)), addr:$dst)]>,
1661 def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1662 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1663 [(store (X86shld (loadi16 addr:$dst), R16:$src2, CL),
1665 Imp<[CL],[]>, TB, OpSize;
1666 def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1667 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1668 [(store (X86shrd (loadi16 addr:$dst), R16:$src2, CL),
1670 Imp<[CL],[]>, TB, OpSize;
1671 def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
1672 (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1673 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1674 [(store (X86shld (loadi16 addr:$dst), R16:$src2,
1675 (i8 imm:$src3)), addr:$dst)]>,
1677 def SHRD16mri8 : Ii8<0xAC, MRMDestMem,
1678 (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1679 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1680 [(store (X86shrd (loadi16 addr:$dst), R16:$src2,
1681 (i8 imm:$src3)), addr:$dst)]>,
1687 let isCommutable = 1 in { // X = ADD Y, Z --> X = ADD Z, Y
1688 def ADD8rr : I<0x00, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1689 "add{b} {$src2, $dst|$dst, $src2}",
1690 [(set R8:$dst, (add R8:$src1, R8:$src2))]>;
1691 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1692 def ADD16rr : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1693 "add{w} {$src2, $dst|$dst, $src2}",
1694 [(set R16:$dst, (add R16:$src1, R16:$src2))]>, OpSize;
1695 def ADD32rr : I<0x01, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1696 "add{l} {$src2, $dst|$dst, $src2}",
1697 [(set R32:$dst, (add R32:$src1, R32:$src2))]>;
1698 } // end isConvertibleToThreeAddress
1699 } // end isCommutable
1700 def ADD8rm : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1701 "add{b} {$src2, $dst|$dst, $src2}",
1702 [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>;
1703 def ADD16rm : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1704 "add{w} {$src2, $dst|$dst, $src2}",
1705 [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize;
1706 def ADD32rm : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1707 "add{l} {$src2, $dst|$dst, $src2}",
1708 [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>;
1710 def ADD8ri : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1711 "add{b} {$src2, $dst|$dst, $src2}",
1712 [(set R8:$dst, (add R8:$src1, imm:$src2))]>;
1714 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1715 def ADD16ri : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1716 "add{w} {$src2, $dst|$dst, $src2}",
1717 [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize;
1718 def ADD32ri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1719 "add{l} {$src2, $dst|$dst, $src2}",
1720 [(set R32:$dst, (add R32:$src1, imm:$src2))]>;
1723 def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1724 "add{w} {$src2, $dst|$dst, $src2}",
1725 [(set R16:$dst, (add R16:$src1, i16immSExt8:$src2))]>,
1727 def ADD32ri8 : Ii8<0x83, MRM0r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1728 "add{l} {$src2, $dst|$dst, $src2}",
1729 [(set R32:$dst, (add R32:$src1, i32immSExt8:$src2))]>;
1731 let isTwoAddress = 0 in {
1732 def ADD8mr : I<0x00, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1733 "add{b} {$src2, $dst|$dst, $src2}",
1734 [(store (add (load addr:$dst), R8:$src2), addr:$dst)]>;
1735 def ADD16mr : I<0x01, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1736 "add{w} {$src2, $dst|$dst, $src2}",
1737 [(store (add (load addr:$dst), R16:$src2), addr:$dst)]>,
1739 def ADD32mr : I<0x01, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1740 "add{l} {$src2, $dst|$dst, $src2}",
1741 [(store (add (load addr:$dst), R32:$src2), addr:$dst)]>;
1742 def ADD8mi : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
1743 "add{b} {$src2, $dst|$dst, $src2}",
1744 [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1745 def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
1746 "add{w} {$src2, $dst|$dst, $src2}",
1747 [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1749 def ADD32mi : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
1750 "add{l} {$src2, $dst|$dst, $src2}",
1751 [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1752 def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
1753 "add{w} {$src2, $dst|$dst, $src2}",
1754 [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1756 def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
1757 "add{l} {$src2, $dst|$dst, $src2}",
1758 [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1761 let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y
1762 def ADC32rr : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1763 "adc{l} {$src2, $dst|$dst, $src2}",
1764 [(set R32:$dst, (adde R32:$src1, R32:$src2))]>;
1766 def ADC32rm : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1767 "adc{l} {$src2, $dst|$dst, $src2}",
1768 [(set R32:$dst, (adde R32:$src1, (load addr:$src2)))]>;
1769 def ADC32ri : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1770 "adc{l} {$src2, $dst|$dst, $src2}",
1771 [(set R32:$dst, (adde R32:$src1, imm:$src2))]>;
1772 def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1773 "adc{l} {$src2, $dst|$dst, $src2}",
1774 [(set R32:$dst, (adde R32:$src1, i32immSExt8:$src2))]>;
1776 let isTwoAddress = 0 in {
1777 def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1778 "adc{l} {$src2, $dst|$dst, $src2}",
1779 [(store (adde (load addr:$dst), R32:$src2), addr:$dst)]>;
1780 def ADC32mi : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
1781 "adc{l} {$src2, $dst|$dst, $src2}",
1782 [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1783 def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
1784 "adc{l} {$src2, $dst|$dst, $src2}",
1785 [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1788 def SUB8rr : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1789 "sub{b} {$src2, $dst|$dst, $src2}",
1790 [(set R8:$dst, (sub R8:$src1, R8:$src2))]>;
1791 def SUB16rr : I<0x29, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1792 "sub{w} {$src2, $dst|$dst, $src2}",
1793 [(set R16:$dst, (sub R16:$src1, R16:$src2))]>, OpSize;
1794 def SUB32rr : I<0x29, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1795 "sub{l} {$src2, $dst|$dst, $src2}",
1796 [(set R32:$dst, (sub R32:$src1, R32:$src2))]>;
1797 def SUB8rm : I<0x2A, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1798 "sub{b} {$src2, $dst|$dst, $src2}",
1799 [(set R8:$dst, (sub R8:$src1, (load addr:$src2)))]>;
1800 def SUB16rm : I<0x2B, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1801 "sub{w} {$src2, $dst|$dst, $src2}",
1802 [(set R16:$dst, (sub R16:$src1, (load addr:$src2)))]>, OpSize;
1803 def SUB32rm : I<0x2B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1804 "sub{l} {$src2, $dst|$dst, $src2}",
1805 [(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
1807 def SUB8ri : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1808 "sub{b} {$src2, $dst|$dst, $src2}",
1809 [(set R8:$dst, (sub R8:$src1, imm:$src2))]>;
1810 def SUB16ri : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1811 "sub{w} {$src2, $dst|$dst, $src2}",
1812 [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize;
1813 def SUB32ri : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1814 "sub{l} {$src2, $dst|$dst, $src2}",
1815 [(set R32:$dst, (sub R32:$src1, imm:$src2))]>;
1816 def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1817 "sub{w} {$src2, $dst|$dst, $src2}",
1818 [(set R16:$dst, (sub R16:$src1, i16immSExt8:$src2))]>,
1820 def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1821 "sub{l} {$src2, $dst|$dst, $src2}",
1822 [(set R32:$dst, (sub R32:$src1, i32immSExt8:$src2))]>;
1823 let isTwoAddress = 0 in {
1824 def SUB8mr : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1825 "sub{b} {$src2, $dst|$dst, $src2}",
1826 [(store (sub (load addr:$dst), R8:$src2), addr:$dst)]>;
1827 def SUB16mr : I<0x29, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1828 "sub{w} {$src2, $dst|$dst, $src2}",
1829 [(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
1831 def SUB32mr : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1832 "sub{l} {$src2, $dst|$dst, $src2}",
1833 [(store (sub (load addr:$dst), R32:$src2), addr:$dst)]>;
1834 def SUB8mi : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2),
1835 "sub{b} {$src2, $dst|$dst, $src2}",
1836 [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1837 def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2),
1838 "sub{w} {$src2, $dst|$dst, $src2}",
1839 [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1841 def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2),
1842 "sub{l} {$src2, $dst|$dst, $src2}",
1843 [(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1844 def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2),
1845 "sub{w} {$src2, $dst|$dst, $src2}",
1846 [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1848 def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2),
1849 "sub{l} {$src2, $dst|$dst, $src2}",
1850 [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1853 def SBB32rr : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1854 "sbb{l} {$src2, $dst|$dst, $src2}",
1855 [(set R32:$dst, (sube R32:$src1, R32:$src2))]>;
1857 let isTwoAddress = 0 in {
1858 def SBB32mr : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1859 "sbb{l} {$src2, $dst|$dst, $src2}",
1860 [(store (sube (load addr:$dst), R32:$src2), addr:$dst)]>;
1861 def SBB8mi : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2),
1862 "sbb{b} {$src2, $dst|$dst, $src2}",
1863 [(store (sube (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1864 def SBB32mi : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2),
1865 "sbb{l} {$src2, $dst|$dst, $src2}",
1866 [(store (sube (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1867 def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2),
1868 "sbb{l} {$src2, $dst|$dst, $src2}",
1869 [(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1871 def SBB32rm : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1872 "sbb{l} {$src2, $dst|$dst, $src2}",
1873 [(set R32:$dst, (sube R32:$src1, (load addr:$src2)))]>;
1874 def SBB32ri : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1875 "sbb{l} {$src2, $dst|$dst, $src2}",
1876 [(set R32:$dst, (sube R32:$src1, imm:$src2))]>;
1877 def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1878 "sbb{l} {$src2, $dst|$dst, $src2}",
1879 [(set R32:$dst, (sube R32:$src1, i32immSExt8:$src2))]>;
1881 let isCommutable = 1 in { // X = IMUL Y, Z --> X = IMUL Z, Y
1882 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
1883 "imul{w} {$src2, $dst|$dst, $src2}",
1884 [(set R16:$dst, (mul R16:$src1, R16:$src2))]>, TB, OpSize;
1885 def IMUL32rr : I<0xAF, MRMSrcReg, (ops R32:$dst, R32:$src1, R32:$src2),
1886 "imul{l} {$src2, $dst|$dst, $src2}",
1887 [(set R32:$dst, (mul R32:$src1, R32:$src2))]>, TB;
1889 def IMUL16rm : I<0xAF, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1890 "imul{w} {$src2, $dst|$dst, $src2}",
1891 [(set R16:$dst, (mul R16:$src1, (load addr:$src2)))]>,
1893 def IMUL32rm : I<0xAF, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1894 "imul{l} {$src2, $dst|$dst, $src2}",
1895 [(set R32:$dst, (mul R32:$src1, (load addr:$src2)))]>, TB;
1897 } // end Two Address instructions
1899 // Suprisingly enough, these are not two address instructions!
1900 def IMUL16rri : Ii16<0x69, MRMSrcReg, // R16 = R16*I16
1901 (ops R16:$dst, R16:$src1, i16imm:$src2),
1902 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1903 [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize;
1904 def IMUL32rri : Ii32<0x69, MRMSrcReg, // R32 = R32*I32
1905 (ops R32:$dst, R32:$src1, i32imm:$src2),
1906 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1907 [(set R32:$dst, (mul R32:$src1, imm:$src2))]>;
1908 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // R16 = R16*I8
1909 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1910 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1911 [(set R16:$dst, (mul R16:$src1, i16immSExt8:$src2))]>,
1913 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // R32 = R32*I8
1914 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1915 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1916 [(set R32:$dst, (mul R32:$src1, i32immSExt8:$src2))]>;
1918 def IMUL16rmi : Ii16<0x69, MRMSrcMem, // R16 = [mem16]*I16
1919 (ops R16:$dst, i16mem:$src1, i16imm:$src2),
1920 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1921 [(set R16:$dst, (mul (load addr:$src1), imm:$src2))]>,
1923 def IMUL32rmi : Ii32<0x69, MRMSrcMem, // R32 = [mem32]*I32
1924 (ops R32:$dst, i32mem:$src1, i32imm:$src2),
1925 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1926 [(set R32:$dst, (mul (load addr:$src1), imm:$src2))]>;
1927 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // R16 = [mem16]*I8
1928 (ops R16:$dst, i16mem:$src1, i16i8imm :$src2),
1929 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1930 [(set R16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
1932 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // R32 = [mem32]*I8
1933 (ops R32:$dst, i32mem:$src1, i32i8imm: $src2),
1934 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1935 [(set R32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
1937 //===----------------------------------------------------------------------===//
1938 // Test instructions are just like AND, except they don't generate a result.
1940 let isCommutable = 1 in { // TEST X, Y --> TEST Y, X
1941 def TEST8rr : I<0x84, MRMDestReg, (ops R8:$src1, R8:$src2),
1942 "test{b} {$src2, $src1|$src1, $src2}",
1943 [(X86test R8:$src1, R8:$src2)]>;
1944 def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
1945 "test{w} {$src2, $src1|$src1, $src2}",
1946 [(X86test R16:$src1, R16:$src2)]>, OpSize;
1947 def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
1948 "test{l} {$src2, $src1|$src1, $src2}",
1949 [(X86test R32:$src1, R32:$src2)]>;
1951 def TEST8mr : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
1952 "test{b} {$src2, $src1|$src1, $src2}",
1953 [(X86test (loadi8 addr:$src1), R8:$src2)]>;
1954 def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
1955 "test{w} {$src2, $src1|$src1, $src2}",
1956 [(X86test (loadi16 addr:$src1), R16:$src2)]>,
1958 def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
1959 "test{l} {$src2, $src1|$src1, $src2}",
1960 [(X86test (loadi32 addr:$src1), R32:$src2)]>;
1961 def TEST8rm : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
1962 "test{b} {$src2, $src1|$src1, $src2}",
1963 [(X86test R8:$src1, (loadi8 addr:$src2))]>;
1964 def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
1965 "test{w} {$src2, $src1|$src1, $src2}",
1966 [(X86test R16:$src1, (loadi16 addr:$src2))]>,
1968 def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
1969 "test{l} {$src2, $src1|$src1, $src2}",
1970 [(X86test R32:$src1, (loadi32 addr:$src2))]>;
1972 def TEST8ri : Ii8 <0xF6, MRM0r, // flags = R8 & imm8
1973 (ops R8:$src1, i8imm:$src2),
1974 "test{b} {$src2, $src1|$src1, $src2}",
1975 [(X86test R8:$src1, imm:$src2)]>;
1976 def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16
1977 (ops R16:$src1, i16imm:$src2),
1978 "test{w} {$src2, $src1|$src1, $src2}",
1979 [(X86test R16:$src1, imm:$src2)]>, OpSize;
1980 def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32
1981 (ops R32:$src1, i32imm:$src2),
1982 "test{l} {$src2, $src1|$src1, $src2}",
1983 [(X86test R32:$src1, imm:$src2)]>;
1984 def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
1985 (ops i8mem:$src1, i8imm:$src2),
1986 "test{b} {$src2, $src1|$src1, $src2}",
1987 [(X86test (loadi8 addr:$src1), imm:$src2)]>;
1988 def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
1989 (ops i16mem:$src1, i16imm:$src2),
1990 "test{w} {$src2, $src1|$src1, $src2}",
1991 [(X86test (loadi16 addr:$src1), imm:$src2)]>,
1993 def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
1994 (ops i32mem:$src1, i32imm:$src2),
1995 "test{l} {$src2, $src1|$src1, $src2}",
1996 [(X86test (loadi32 addr:$src1), imm:$src2)]>;
1999 // Condition code ops, incl. set if equal/not equal/...
2000 def SAHF : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>; // flags = AH
2001 def LAHF : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>; // AH = flags
2003 def SETEr : I<0x94, MRM0r,
2006 [(set R8:$dst, (X86setcc X86_COND_E))]>,
2008 def SETEm : I<0x94, MRM0m,
2011 [(store (X86setcc X86_COND_E), addr:$dst)]>,
2013 def SETNEr : I<0x95, MRM0r,
2016 [(set R8:$dst, (X86setcc X86_COND_NE))]>,
2018 def SETNEm : I<0x95, MRM0m,
2021 [(store (X86setcc X86_COND_NE), addr:$dst)]>,
2023 def SETLr : I<0x9C, MRM0r,
2026 [(set R8:$dst, (X86setcc X86_COND_L))]>,
2027 TB; // R8 = < signed
2028 def SETLm : I<0x9C, MRM0m,
2031 [(store (X86setcc X86_COND_L), addr:$dst)]>,
2032 TB; // [mem8] = < signed
2033 def SETGEr : I<0x9D, MRM0r,
2036 [(set R8:$dst, (X86setcc X86_COND_GE))]>,
2037 TB; // R8 = >= signed
2038 def SETGEm : I<0x9D, MRM0m,
2041 [(store (X86setcc X86_COND_GE), addr:$dst)]>,
2042 TB; // [mem8] = >= signed
2043 def SETLEr : I<0x9E, MRM0r,
2046 [(set R8:$dst, (X86setcc X86_COND_LE))]>,
2047 TB; // R8 = <= signed
2048 def SETLEm : I<0x9E, MRM0m,
2051 [(store (X86setcc X86_COND_LE), addr:$dst)]>,
2052 TB; // [mem8] = <= signed
2053 def SETGr : I<0x9F, MRM0r,
2056 [(set R8:$dst, (X86setcc X86_COND_G))]>,
2057 TB; // R8 = > signed
2058 def SETGm : I<0x9F, MRM0m,
2061 [(store (X86setcc X86_COND_G), addr:$dst)]>,
2062 TB; // [mem8] = > signed
2064 def SETBr : I<0x92, MRM0r,
2067 [(set R8:$dst, (X86setcc X86_COND_B))]>,
2068 TB; // R8 = < unsign
2069 def SETBm : I<0x92, MRM0m,
2072 [(store (X86setcc X86_COND_B), addr:$dst)]>,
2073 TB; // [mem8] = < unsign
2074 def SETAEr : I<0x93, MRM0r,
2077 [(set R8:$dst, (X86setcc X86_COND_AE))]>,
2078 TB; // R8 = >= unsign
2079 def SETAEm : I<0x93, MRM0m,
2082 [(store (X86setcc X86_COND_AE), addr:$dst)]>,
2083 TB; // [mem8] = >= unsign
2084 def SETBEr : I<0x96, MRM0r,
2087 [(set R8:$dst, (X86setcc X86_COND_BE))]>,
2088 TB; // R8 = <= unsign
2089 def SETBEm : I<0x96, MRM0m,
2092 [(store (X86setcc X86_COND_BE), addr:$dst)]>,
2093 TB; // [mem8] = <= unsign
2094 def SETAr : I<0x97, MRM0r,
2097 [(set R8:$dst, (X86setcc X86_COND_A))]>,
2098 TB; // R8 = > signed
2099 def SETAm : I<0x97, MRM0m,
2102 [(store (X86setcc X86_COND_A), addr:$dst)]>,
2103 TB; // [mem8] = > signed
2105 def SETSr : I<0x98, MRM0r,
2108 [(set R8:$dst, (X86setcc X86_COND_S))]>,
2109 TB; // R8 = <sign bit>
2110 def SETSm : I<0x98, MRM0m,
2113 [(store (X86setcc X86_COND_S), addr:$dst)]>,
2114 TB; // [mem8] = <sign bit>
2115 def SETNSr : I<0x99, MRM0r,
2118 [(set R8:$dst, (X86setcc X86_COND_NS))]>,
2119 TB; // R8 = !<sign bit>
2120 def SETNSm : I<0x99, MRM0m,
2123 [(store (X86setcc X86_COND_NS), addr:$dst)]>,
2124 TB; // [mem8] = !<sign bit>
2125 def SETPr : I<0x9A, MRM0r,
2128 [(set R8:$dst, (X86setcc X86_COND_P))]>,
2130 def SETPm : I<0x9A, MRM0m,
2133 [(store (X86setcc X86_COND_P), addr:$dst)]>,
2134 TB; // [mem8] = parity
2135 def SETNPr : I<0x9B, MRM0r,
2138 [(set R8:$dst, (X86setcc X86_COND_NP))]>,
2139 TB; // R8 = not parity
2140 def SETNPm : I<0x9B, MRM0m,
2143 [(store (X86setcc X86_COND_NP), addr:$dst)]>,
2144 TB; // [mem8] = not parity
2146 // Integer comparisons
2147 def CMP8rr : I<0x38, MRMDestReg,
2148 (ops R8 :$src1, R8 :$src2),
2149 "cmp{b} {$src2, $src1|$src1, $src2}",
2150 [(X86cmp R8:$src1, R8:$src2)]>;
2151 def CMP16rr : I<0x39, MRMDestReg,
2152 (ops R16:$src1, R16:$src2),
2153 "cmp{w} {$src2, $src1|$src1, $src2}",
2154 [(X86cmp R16:$src1, R16:$src2)]>, OpSize;
2155 def CMP32rr : I<0x39, MRMDestReg,
2156 (ops R32:$src1, R32:$src2),
2157 "cmp{l} {$src2, $src1|$src1, $src2}",
2158 [(X86cmp R32:$src1, R32:$src2)]>;
2159 def CMP8mr : I<0x38, MRMDestMem,
2160 (ops i8mem :$src1, R8 :$src2),
2161 "cmp{b} {$src2, $src1|$src1, $src2}",
2162 [(X86cmp (loadi8 addr:$src1), R8:$src2)]>;
2163 def CMP16mr : I<0x39, MRMDestMem,
2164 (ops i16mem:$src1, R16:$src2),
2165 "cmp{w} {$src2, $src1|$src1, $src2}",
2166 [(X86cmp (loadi16 addr:$src1), R16:$src2)]>, OpSize;
2167 def CMP32mr : I<0x39, MRMDestMem,
2168 (ops i32mem:$src1, R32:$src2),
2169 "cmp{l} {$src2, $src1|$src1, $src2}",
2170 [(X86cmp (loadi32 addr:$src1), R32:$src2)]>;
2171 def CMP8rm : I<0x3A, MRMSrcMem,
2172 (ops R8 :$src1, i8mem :$src2),
2173 "cmp{b} {$src2, $src1|$src1, $src2}",
2174 [(X86cmp R8:$src1, (loadi8 addr:$src2))]>;
2175 def CMP16rm : I<0x3B, MRMSrcMem,
2176 (ops R16:$src1, i16mem:$src2),
2177 "cmp{w} {$src2, $src1|$src1, $src2}",
2178 [(X86cmp R16:$src1, (loadi16 addr:$src2))]>, OpSize;
2179 def CMP32rm : I<0x3B, MRMSrcMem,
2180 (ops R32:$src1, i32mem:$src2),
2181 "cmp{l} {$src2, $src1|$src1, $src2}",
2182 [(X86cmp R32:$src1, (loadi32 addr:$src2))]>;
2183 def CMP8ri : Ii8<0x80, MRM7r,
2184 (ops R8:$src1, i8imm:$src2),
2185 "cmp{b} {$src2, $src1|$src1, $src2}",
2186 [(X86cmp R8:$src1, imm:$src2)]>;
2187 def CMP16ri : Ii16<0x81, MRM7r,
2188 (ops R16:$src1, i16imm:$src2),
2189 "cmp{w} {$src2, $src1|$src1, $src2}",
2190 [(X86cmp R16:$src1, imm:$src2)]>, OpSize;
2191 def CMP32ri : Ii32<0x81, MRM7r,
2192 (ops R32:$src1, i32imm:$src2),
2193 "cmp{l} {$src2, $src1|$src1, $src2}",
2194 [(X86cmp R32:$src1, imm:$src2)]>;
2195 def CMP8mi : Ii8 <0x80, MRM7m,
2196 (ops i8mem :$src1, i8imm :$src2),
2197 "cmp{b} {$src2, $src1|$src1, $src2}",
2198 [(X86cmp (loadi8 addr:$src1), imm:$src2)]>;
2199 def CMP16mi : Ii16<0x81, MRM7m,
2200 (ops i16mem:$src1, i16imm:$src2),
2201 "cmp{w} {$src2, $src1|$src1, $src2}",
2202 [(X86cmp (loadi16 addr:$src1), imm:$src2)]>, OpSize;
2203 def CMP32mi : Ii32<0x81, MRM7m,
2204 (ops i32mem:$src1, i32imm:$src2),
2205 "cmp{l} {$src2, $src1|$src1, $src2}",
2206 [(X86cmp (loadi32 addr:$src1), imm:$src2)]>;
2207 def CMP16ri8 : Ii8<0x83, MRM7r,
2208 (ops R16:$src1, i16i8imm:$src2),
2209 "cmp{w} {$src2, $src1|$src1, $src2}",
2210 [(X86cmp R16:$src1, i16immSExt8:$src2)]>, OpSize;
2211 def CMP16mi8 : Ii8<0x83, MRM7m,
2212 (ops i16mem:$src1, i16i8imm:$src2),
2213 "cmp{w} {$src2, $src1|$src1, $src2}",
2214 [(X86cmp (loadi16 addr:$src1), i16immSExt8:$src2)]>, OpSize;
2215 def CMP32mi8 : Ii8<0x83, MRM7m,
2216 (ops i32mem:$src1, i32i8imm:$src2),
2217 "cmp{l} {$src2, $src1|$src1, $src2}",
2218 [(X86cmp (loadi32 addr:$src1), i32immSExt8:$src2)]>;
2219 def CMP32ri8 : Ii8<0x83, MRM7r,
2220 (ops R32:$src1, i32i8imm:$src2),
2221 "cmp{l} {$src2, $src1|$src1, $src2}",
2222 [(X86cmp R32:$src1, i32immSExt8:$src2)]>;
2224 // Sign/Zero extenders
2225 def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
2226 "movs{bw|x} {$src, $dst|$dst, $src}",
2227 [(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
2228 def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2229 "movs{bw|x} {$src, $dst|$dst, $src}",
2230 [(set R16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
2231 def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
2232 "movs{bl|x} {$src, $dst|$dst, $src}",
2233 [(set R32:$dst, (sext R8:$src))]>, TB;
2234 def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2235 "movs{bl|x} {$src, $dst|$dst, $src}",
2236 [(set R32:$dst, (sextloadi32i8 addr:$src))]>, TB;
2237 def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
2238 "movs{wl|x} {$src, $dst|$dst, $src}",
2239 [(set R32:$dst, (sext R16:$src))]>, TB;
2240 def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2241 "movs{wl|x} {$src, $dst|$dst, $src}",
2242 [(set R32:$dst, (sextloadi32i16 addr:$src))]>, TB;
2244 def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
2245 "movz{bw|x} {$src, $dst|$dst, $src}",
2246 [(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
2247 def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
2248 "movz{bw|x} {$src, $dst|$dst, $src}",
2249 [(set R16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
2250 def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
2251 "movz{bl|x} {$src, $dst|$dst, $src}",
2252 [(set R32:$dst, (zext R8:$src))]>, TB;
2253 def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
2254 "movz{bl|x} {$src, $dst|$dst, $src}",
2255 [(set R32:$dst, (zextloadi32i8 addr:$src))]>, TB;
2256 def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
2257 "movz{wl|x} {$src, $dst|$dst, $src}",
2258 [(set R32:$dst, (zext R16:$src))]>, TB;
2259 def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
2260 "movz{wl|x} {$src, $dst|$dst, $src}",
2261 [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB;
2263 //===----------------------------------------------------------------------===//
2264 // Miscellaneous Instructions
2265 //===----------------------------------------------------------------------===//
2267 def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
2268 TB, Imp<[],[EAX,EDX]>;
2270 //===----------------------------------------------------------------------===//
2271 // Alias Instructions
2272 //===----------------------------------------------------------------------===//
2274 // Alias instructions that map movr0 to xor.
2275 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
2276 def MOV8r0 : I<0x30, MRMInitReg, (ops R8 :$dst),
2277 "xor{b} $dst, $dst",
2278 [(set R8:$dst, 0)]>;
2279 def MOV16r0 : I<0x31, MRMInitReg, (ops R16:$dst),
2280 "xor{w} $dst, $dst",
2281 [(set R16:$dst, 0)]>, OpSize;
2282 def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst),
2283 "xor{l} $dst, $dst",
2284 [(set R32:$dst, 0)]>;
2286 //===----------------------------------------------------------------------===//
2287 // DWARF Pseudo Instructions
2290 def DWARF_LOC : I<0, Pseudo, (ops i32imm:$line, i32imm:$col, i32imm:$file),
2291 "; .loc $file, $line, $col",
2292 [(dwarf_loc (i32 imm:$line), (i32 imm:$col),
2295 def DWARF_LABEL : I<0, Pseudo, (ops i32imm:$id),
2296 "\nLdebug_loc${id:debug}:",
2297 [(dwarf_label (i32 imm:$id))]>;
2299 //===----------------------------------------------------------------------===//
2300 // Non-Instruction Patterns
2301 //===----------------------------------------------------------------------===//
2303 // ConstantPool GlobalAddress, ExternalSymbol
2304 def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>;
2305 def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>;
2306 def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>;
2308 def : Pat<(add R32:$src1, (X86Wrapper tconstpool:$src2)),
2309 (ADD32ri R32:$src1, tconstpool:$src2)>;
2310 def : Pat<(add R32:$src1, (X86Wrapper tglobaladdr :$src2)),
2311 (ADD32ri R32:$src1, tglobaladdr:$src2)>;
2312 def : Pat<(add R32:$src1, (X86Wrapper texternalsym:$src2)),
2313 (ADD32ri R32:$src1, texternalsym:$src2)>;
2315 def : Pat<(store (X86Wrapper tconstpool:$src), addr:$dst),
2316 (MOV32mi addr:$dst, tconstpool:$src)>;
2317 def : Pat<(store (X86Wrapper tglobaladdr:$src), addr:$dst),
2318 (MOV32mi addr:$dst, tglobaladdr:$src)>;
2319 def : Pat<(store (X86Wrapper texternalsym:$src), addr:$dst),
2320 (MOV32mi addr:$dst, texternalsym:$src)>;
2323 def : Pat<(X86call tglobaladdr:$dst),
2324 (CALLpcrel32 tglobaladdr:$dst)>;
2325 def : Pat<(X86call texternalsym:$dst),
2326 (CALLpcrel32 texternalsym:$dst)>;
2328 // X86 specific add which produces a flag.
2329 def : Pat<(addc R32:$src1, R32:$src2),
2330 (ADD32rr R32:$src1, R32:$src2)>;
2331 def : Pat<(addc R32:$src1, (load addr:$src2)),
2332 (ADD32rm R32:$src1, addr:$src2)>;
2333 def : Pat<(addc R32:$src1, imm:$src2),
2334 (ADD32ri R32:$src1, imm:$src2)>;
2335 def : Pat<(addc R32:$src1, i32immSExt8:$src2),
2336 (ADD32ri8 R32:$src1, i32immSExt8:$src2)>;
2338 def : Pat<(subc R32:$src1, R32:$src2),
2339 (SUB32rr R32:$src1, R32:$src2)>;
2340 def : Pat<(subc R32:$src1, (load addr:$src2)),
2341 (SUB32rm R32:$src1, addr:$src2)>;
2342 def : Pat<(subc R32:$src1, imm:$src2),
2343 (SUB32ri R32:$src1, imm:$src2)>;
2344 def : Pat<(subc R32:$src1, i32immSExt8:$src2),
2345 (SUB32ri8 R32:$src1, i32immSExt8:$src2)>;
2347 def : Pat<(truncstore (i8 imm:$src), addr:$dst, i1),
2348 (MOV8mi addr:$dst, imm:$src)>;
2349 def : Pat<(truncstore R8:$src, addr:$dst, i1),
2350 (MOV8mr addr:$dst, R8:$src)>;
2352 // {s|z}extload bool -> {s|z}extload byte
2353 def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>;
2354 def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>;
2355 def : Pat<(zextloadi8i1 addr:$src), (MOV8rm addr:$src)>;
2356 def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
2357 def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
2359 // extload bool -> extload byte
2360 def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
2363 def : Pat<(i16 (anyext R8 :$src)), (MOVZX16rr8 R8 :$src)>;
2364 def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8 R8 :$src)>;
2365 def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
2366 def : Pat<(i16 (anyext (loadi8 addr:$src))), (MOVZX16rm8 addr:$src)>;
2367 def : Pat<(i32 (anyext (loadi8 addr:$src))), (MOVZX32rm8 addr:$src)>;
2368 def : Pat<(i32 (anyext (loadi16 addr:$src))), (MOVZX32rm16 addr:$src)>;
2370 //===----------------------------------------------------------------------===//
2372 //===----------------------------------------------------------------------===//
2374 // (shl x, 1) ==> (add x, x)
2375 def : Pat<(shl R8 :$src1, (i8 1)), (ADD8rr R8 :$src1, R8 :$src1)>;
2376 def : Pat<(shl R16:$src1, (i8 1)), (ADD16rr R16:$src1, R16:$src1)>;
2377 def : Pat<(shl R32:$src1, (i8 1)), (ADD32rr R32:$src1, R32:$src1)>;
2379 // (or (x >> c) | (y << (32 - c))) ==> (shrd32 x, y, c)
2380 def : Pat<(or (srl R32:$src1, CL:$amt),
2381 (shl R32:$src2, (sub 32, CL:$amt))),
2382 (SHRD32rrCL R32:$src1, R32:$src2)>;
2384 def : Pat<(store (or (srl (loadi32 addr:$dst), CL:$amt),
2385 (shl R32:$src2, (sub 32, CL:$amt))), addr:$dst),
2386 (SHRD32mrCL addr:$dst, R32:$src2)>;
2388 // (or (x << c) | (y >> (32 - c))) ==> (shld32 x, y, c)
2389 def : Pat<(or (shl R32:$src1, CL:$amt),
2390 (srl R32:$src2, (sub 32, CL:$amt))),
2391 (SHLD32rrCL R32:$src1, R32:$src2)>;
2393 def : Pat<(store (or (shl (loadi32 addr:$dst), CL:$amt),
2394 (srl R32:$src2, (sub 32, CL:$amt))), addr:$dst),
2395 (SHLD32mrCL addr:$dst, R32:$src2)>;
2397 // (or (x >> c) | (y << (16 - c))) ==> (shrd16 x, y, c)
2398 def : Pat<(or (srl R16:$src1, CL:$amt),
2399 (shl R16:$src2, (sub 16, CL:$amt))),
2400 (SHRD16rrCL R16:$src1, R16:$src2)>;
2402 def : Pat<(store (or (srl (loadi16 addr:$dst), CL:$amt),
2403 (shl R16:$src2, (sub 16, CL:$amt))), addr:$dst),
2404 (SHRD16mrCL addr:$dst, R16:$src2)>;
2406 // (or (x << c) | (y >> (16 - c))) ==> (shld16 x, y, c)
2407 def : Pat<(or (shl R16:$src1, CL:$amt),
2408 (srl R16:$src2, (sub 16, CL:$amt))),
2409 (SHLD16rrCL R16:$src1, R16:$src2)>;
2411 def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt),
2412 (srl R16:$src2, (sub 16, CL:$amt))), addr:$dst),
2413 (SHLD16mrCL addr:$dst, R16:$src2)>;
2416 //===----------------------------------------------------------------------===//
2417 // Floating Point Stack Support
2418 //===----------------------------------------------------------------------===//
2420 include "X86InstrFPStack.td"
2422 //===----------------------------------------------------------------------===//
2423 // MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2)
2424 //===----------------------------------------------------------------------===//
2426 include "X86InstrMMX.td"
2428 //===----------------------------------------------------------------------===//
2429 // XMM Floating point support (requires SSE / SSE2)
2430 //===----------------------------------------------------------------------===//
2432 include "X86InstrSSE.td"