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 SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisInt<1>,
23 def SDTX86Cmov : SDTypeProfile<1, 4,
24 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
25 SDTCisVT<3, OtherVT>, SDTCisVT<4, FlagVT>]>;
27 def SDTX86BrCond : SDTypeProfile<0, 3,
28 [SDTCisVT<0, OtherVT>,
29 SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
31 def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, FlagVT>]>;
33 def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisFP<0>,
34 SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
36 def SDTX86FpSet : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
38 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>;
39 def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>;
41 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, []>;
42 def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>;
44 def X86retflag: SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
46 def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain]>;
48 def X86fpset : SDNode<"X86ISD::FP_SET_RESULT",
49 SDTX86FpSet, [SDNPHasChain]>;
51 //===----------------------------------------------------------------------===//
52 // X86 Operand Definitions.
55 // *mem - Operand definitions for the funky X86 addressing mode operands.
57 class X86MemOperand<string printMethod> : Operand<i32> {
58 let PrintMethod = printMethod;
59 let NumMIOperands = 4;
60 let MIOperandInfo = (ops R32, i8imm, R32, i32imm);
63 def i8mem : X86MemOperand<"printi8mem">;
64 def i16mem : X86MemOperand<"printi16mem">;
65 def i32mem : X86MemOperand<"printi32mem">;
66 def i64mem : X86MemOperand<"printi64mem">;
67 def f32mem : X86MemOperand<"printf32mem">;
68 def f64mem : X86MemOperand<"printf64mem">;
69 def f80mem : X86MemOperand<"printf80mem">;
71 def SSECC : Operand<i8> {
72 let PrintMethod = "printSSECC";
75 // A couple of more descriptive operand definitions.
76 // 16-bits but only 8 bits are significant.
77 def i16i8imm : Operand<i16>;
78 // 32-bits but only 8 bits are significant.
79 def i32i8imm : Operand<i32>;
81 // PCRelative calls need special operand formatting.
82 let PrintMethod = "printCallOperand" in
83 def calltarget : Operand<i32>;
85 // Branch targets have OtherVT type.
86 def brtarget : Operand<OtherVT>;
88 //===----------------------------------------------------------------------===//
89 // X86 Complex Pattern Definitions.
92 // Define X86 specific addressing mode.
93 def addr : ComplexPattern<i32, 4, "SelectAddr", []>;
94 def leaaddr : ComplexPattern<i32, 4, "SelectLEAAddr",
96 frameindex, constpool, globaladdr, externalsym]>;
98 //===----------------------------------------------------------------------===//
99 // X86 Instruction Format Definitions.
102 // Format specifies the encoding used by the instruction. This is part of the
103 // ad-hoc solution used to emit machine instruction encodings by our machine
105 class Format<bits<5> val> {
109 def Pseudo : Format<0>; def RawFrm : Format<1>;
110 def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
111 def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
112 def MRMSrcMem : Format<6>;
113 def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
114 def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
115 def MRM6r : Format<22>; def MRM7r : Format<23>;
116 def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
117 def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
118 def MRM6m : Format<30>; def MRM7m : Format<31>;
120 //===----------------------------------------------------------------------===//
121 // X86 Instruction Predicate Definitions.
122 def HasSSE1 : Predicate<"X86Vector >= SSE">;
123 def HasSSE2 : Predicate<"X86Vector >= SSE2">;
124 def HasSSE3 : Predicate<"X86Vector >= SSE3">;
126 //===----------------------------------------------------------------------===//
127 // X86 specific pattern fragments.
130 // ImmType - This specifies the immediate type used by an instruction. This is
131 // part of the ad-hoc solution used to emit machine instruction encodings by our
132 // machine code emitter.
133 class ImmType<bits<2> val> {
136 def NoImm : ImmType<0>;
137 def Imm8 : ImmType<1>;
138 def Imm16 : ImmType<2>;
139 def Imm32 : ImmType<3>;
141 // FPFormat - This specifies what form this FP instruction has. This is used by
142 // the Floating-Point stackifier pass.
143 class FPFormat<bits<3> val> {
146 def NotFP : FPFormat<0>;
147 def ZeroArgFP : FPFormat<1>;
148 def OneArgFP : FPFormat<2>;
149 def OneArgFPRW : FPFormat<3>;
150 def TwoArgFP : FPFormat<4>;
151 def CompareFP : FPFormat<5>;
152 def CondMovFP : FPFormat<6>;
153 def SpecialFP : FPFormat<7>;
156 class X86Inst<bits<8> opcod, Format f, ImmType i, dag ops, string AsmStr>
158 let Namespace = "X86";
160 bits<8> Opcode = opcod;
162 bits<5> FormBits = Form.Value;
164 bits<2> ImmTypeBits = ImmT.Value;
166 dag OperandList = ops;
167 string AsmString = AsmStr;
170 // Attributes specific to X86 instructions...
172 bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix?
174 bits<4> Prefix = 0; // Which prefix byte does this inst have?
175 FPFormat FPForm; // What flavor of FP instruction is this?
176 bits<3> FPFormBits = 0;
179 class Imp<list<Register> uses, list<Register> defs> {
180 list<Register> Uses = uses;
181 list<Register> Defs = defs;
185 // Prefix byte classes which are used to indicate to the ad-hoc machine code
186 // emitter that various prefix bytes are required.
187 class OpSize { bit hasOpSizePrefix = 1; }
188 class TB { bits<4> Prefix = 1; }
189 class REP { bits<4> Prefix = 2; }
190 class D8 { bits<4> Prefix = 3; }
191 class D9 { bits<4> Prefix = 4; }
192 class DA { bits<4> Prefix = 5; }
193 class DB { bits<4> Prefix = 6; }
194 class DC { bits<4> Prefix = 7; }
195 class DD { bits<4> Prefix = 8; }
196 class DE { bits<4> Prefix = 9; }
197 class DF { bits<4> Prefix = 10; }
198 class XD { bits<4> Prefix = 11; }
199 class XS { bits<4> Prefix = 12; }
202 //===----------------------------------------------------------------------===//
203 // Pattern fragments...
205 def i16immSExt8 : PatLeaf<(i16 imm), [{
206 // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit
207 // sign extended field.
208 return (int)N->getValue() == (signed char)N->getValue();
211 def i32immSExt8 : PatLeaf<(i32 imm), [{
212 // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
213 // sign extended field.
214 return (int)N->getValue() == (signed char)N->getValue();
217 def i16immZExt8 : PatLeaf<(i16 imm), [{
218 // i16immZExt8 predicate - True if the 16-bit immediate fits in a 8-bit zero
220 return (unsigned)N->getValue() == (unsigned char)N->getValue();
223 // Helper fragments for loads.
224 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
225 def loadi16 : PatFrag<(ops node:$ptr), (i16 (load node:$ptr))>;
226 def loadi32 : PatFrag<(ops node:$ptr), (i32 (load node:$ptr))>;
227 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
228 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
230 def sextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i1))>;
231 def sextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i1))>;
232 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i8))>;
233 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i8))>;
234 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i16))>;
236 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i1))>;
237 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i1))>;
238 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>;
239 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>;
240 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>;
242 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>;
245 //===----------------------------------------------------------------------===//
246 // Instruction templates...
248 class I<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
249 : X86Inst<o, f, NoImm, ops, asm> {
250 let Pattern = pattern;
252 class Ii8 <bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
253 : X86Inst<o, f, Imm8 , ops, asm> {
254 let Pattern = pattern;
256 class Ii16<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
257 : X86Inst<o, f, Imm16, ops, asm> {
258 let Pattern = pattern;
260 class Ii32<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
261 : X86Inst<o, f, Imm32, ops, asm> {
262 let Pattern = pattern;
265 //===----------------------------------------------------------------------===//
266 // Instruction list...
269 def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE", []>; // PHI node.
270 def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // nop
272 def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN", []>;
273 def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
274 "#ADJCALLSTACKUP", []>;
275 def IMPLICIT_USE : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
276 def IMPLICIT_DEF : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
277 let isTerminator = 1 in
278 let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
279 def FP_REG_KILL : I<0, Pseudo, (ops), "#FP_REG_KILL", []>;
281 //===----------------------------------------------------------------------===//
282 // Control Flow Instructions...
285 // Return instructions.
286 let isTerminator = 1, isReturn = 1, isBarrier = 1 in
287 def RET : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
288 let isTerminator = 1, isReturn = 1, isBarrier = 1 in
289 def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
291 def : Pat<(X86retflag FLAG), (RET)>;
293 // All branches are RawFrm, Void, Branch, and Terminators
294 let isBranch = 1, isTerminator = 1 in
295 class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
296 I<opcode, RawFrm, ops, asm, pattern>;
299 def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
301 def JE : IBr<0x84, (ops brtarget:$dst), "je $dst",
302 [(X86Brcond bb:$dst, SETEQ, STATUS)]>, Imp<[STATUS],[]>, TB;
303 def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
304 [(X86Brcond bb:$dst, SETNE, STATUS)]>, Imp<[STATUS],[]>, TB;
305 def JL : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
306 [(X86Brcond bb:$dst, SETLT, STATUS)]>, Imp<[STATUS],[]>, TB;
307 def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
308 [(X86Brcond bb:$dst, SETLE, STATUS)]>, Imp<[STATUS],[]>, TB;
309 def JG : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
310 [(X86Brcond bb:$dst, SETGT, STATUS)]>, Imp<[STATUS],[]>, TB;
311 def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
312 [(X86Brcond bb:$dst, SETGE, STATUS)]>, Imp<[STATUS],[]>, TB;
314 def JB : IBr<0x82, (ops brtarget:$dst), "jb $dst",
315 [(X86Brcond bb:$dst, SETULT, STATUS)]>, Imp<[STATUS],[]>, TB;
316 def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
317 [(X86Brcond bb:$dst, SETULE, STATUS)]>, Imp<[STATUS],[]>, TB;
318 def JA : IBr<0x87, (ops brtarget:$dst), "ja $dst",
319 [(X86Brcond bb:$dst, SETUGT, STATUS)]>, Imp<[STATUS],[]>, TB;
320 def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
321 [(X86Brcond bb:$dst, SETUGE, STATUS)]>, Imp<[STATUS],[]>, TB;
323 def JS : IBr<0x88, (ops brtarget:$dst), "js $dst", []>, TB;
324 def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst", []>, TB;
325 def JP : IBr<0x8A, (ops brtarget:$dst), "jp $dst", []>, TB;
326 def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", []>, TB;
328 //===----------------------------------------------------------------------===//
329 // Call Instructions...
332 // All calls clobber the non-callee saved registers...
333 let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
334 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
335 def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst", []>;
336 def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst", []>;
337 def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst", []>;
341 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
342 def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst # TAIL CALL", []>;
343 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
344 def TAILJMPr : I<0xFF, MRM4r, (ops R32:$dst), "jmp {*}$dst # TAIL CALL", []>;
345 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
346 def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
347 "jmp {*}$dst # TAIL CALL", []>;
349 // ADJSTACKPTRri - This is a standard ADD32ri instruction, identical in every
350 // way, except that it is marked as being a terminator. This causes the epilog
351 // inserter to insert reloads of callee saved registers BEFORE this. We need
352 // this until we have a more accurate way of tracking where the stack pointer is
353 // within a function.
354 let isTerminator = 1, isTwoAddress = 1 in
355 def ADJSTACKPTRri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
356 "add{l} {$src2, $dst|$dst, $src2}", []>;
358 //===----------------------------------------------------------------------===//
359 // Miscellaneous Instructions...
361 def LEAVE : I<0xC9, RawFrm,
362 (ops), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
363 def POP32r : I<0x58, AddRegFrm,
364 (ops R32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
366 let isTwoAddress = 1 in // R32 = bswap R32
367 def BSWAP32r : I<0xC8, AddRegFrm,
368 (ops R32:$dst, R32:$src), "bswap{l} $dst", []>, TB;
370 def XCHG8rr : I<0x86, MRMDestReg, // xchg R8, R8
371 (ops R8:$src1, R8:$src2),
372 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
373 def XCHG16rr : I<0x87, MRMDestReg, // xchg R16, R16
374 (ops R16:$src1, R16:$src2),
375 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
376 def XCHG32rr : I<0x87, MRMDestReg, // xchg R32, R32
377 (ops R32:$src1, R32:$src2),
378 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
380 def XCHG8mr : I<0x86, MRMDestMem,
381 (ops i8mem:$src1, R8:$src2),
382 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
383 def XCHG16mr : I<0x87, MRMDestMem,
384 (ops i16mem:$src1, R16:$src2),
385 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
386 def XCHG32mr : I<0x87, MRMDestMem,
387 (ops i32mem:$src1, R32:$src2),
388 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
389 def XCHG8rm : I<0x86, MRMSrcMem,
390 (ops R8:$src1, i8mem:$src2),
391 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
392 def XCHG16rm : I<0x87, MRMSrcMem,
393 (ops R16:$src1, i16mem:$src2),
394 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
395 def XCHG32rm : I<0x87, MRMSrcMem,
396 (ops R32:$src1, i32mem:$src2),
397 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
399 def LEA16r : I<0x8D, MRMSrcMem,
400 (ops R16:$dst, i32mem:$src),
401 "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
402 def LEA32r : I<0x8D, MRMSrcMem,
403 (ops R32:$dst, i32mem:$src),
404 "lea{l} {$src|$dst}, {$dst|$src}",
405 [(set R32:$dst, leaaddr:$src)]>;
407 def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}", []>,
408 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
409 def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}", []>,
410 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
411 def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}", []>,
412 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
414 def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}", []>,
415 Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
416 def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}", []>,
417 Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
418 def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}", []>,
419 Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
422 //===----------------------------------------------------------------------===//
423 // Input/Output Instructions...
425 def IN8rr : I<0xEC, RawFrm, (ops),
426 "in{b} {%dx, %al|%AL, %DX}",
427 [(set AL, (readport DX))]>, Imp<[DX], [AL]>;
428 def IN16rr : I<0xED, RawFrm, (ops),
429 "in{w} {%dx, %ax|%AX, %DX}",
430 [(set AX, (readport DX))]>, Imp<[DX], [AX]>, OpSize;
431 def IN32rr : I<0xED, RawFrm, (ops),
432 "in{l} {%dx, %eax|%EAX, %DX}",
433 [(set EAX, (readport DX))]>, Imp<[DX],[EAX]>;
435 def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
436 "in{b} {$port, %al|%AL, $port}",
437 [(set AL, (readport i16immZExt8:$port))]>,
439 def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
440 "in{w} {$port, %ax|%AX, $port}",
441 [(set AX, (readport i16immZExt8:$port))]>,
442 Imp<[], [AX]>, OpSize;
443 def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
444 "in{l} {$port, %eax|%EAX, $port}",
445 [(set EAX, (readport i16immZExt8:$port))]>,
448 def OUT8rr : I<0xEE, RawFrm, (ops),
449 "out{b} {%al, %dx|%DX, %AL}",
450 [(writeport AL, DX)]>, Imp<[DX, AL], []>;
451 def OUT16rr : I<0xEF, RawFrm, (ops),
452 "out{w} {%ax, %dx|%DX, %AX}",
453 [(writeport AX, DX)]>, Imp<[DX, AX], []>, OpSize;
454 def OUT32rr : I<0xEF, RawFrm, (ops),
455 "out{l} {%eax, %dx|%DX, %EAX}",
456 [(writeport EAX, DX)]>, Imp<[DX, EAX], []>;
458 def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
459 "out{b} {%al, $port|$port, %AL}",
460 [(writeport AL, i16immZExt8:$port)]>,
462 def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
463 "out{w} {%ax, $port|$port, %AX}",
464 [(writeport AX, i16immZExt8:$port)]>,
465 Imp<[AX], []>, OpSize;
466 def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
467 "out{l} {%eax, $port|$port, %EAX}",
468 [(writeport EAX, i16immZExt8:$port)]>,
471 //===----------------------------------------------------------------------===//
472 // Move Instructions...
474 def MOV8rr : I<0x88, MRMDestReg, (ops R8 :$dst, R8 :$src),
475 "mov{b} {$src, $dst|$dst, $src}", []>;
476 def MOV16rr : I<0x89, MRMDestReg, (ops R16:$dst, R16:$src),
477 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
478 def MOV32rr : I<0x89, MRMDestReg, (ops R32:$dst, R32:$src),
479 "mov{l} {$src, $dst|$dst, $src}", []>;
480 def MOV8ri : Ii8 <0xB0, AddRegFrm, (ops R8 :$dst, i8imm :$src),
481 "mov{b} {$src, $dst|$dst, $src}",
482 [(set R8:$dst, imm:$src)]>;
483 def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src),
484 "mov{w} {$src, $dst|$dst, $src}",
485 [(set R16:$dst, imm:$src)]>, OpSize;
486 def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src),
487 "mov{l} {$src, $dst|$dst, $src}",
488 [(set R32:$dst, imm:$src)]>;
489 def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
490 "mov{b} {$src, $dst|$dst, $src}",
491 [(store (i8 imm:$src), addr:$dst)]>;
492 def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src),
493 "mov{w} {$src, $dst|$dst, $src}",
494 [(store (i16 imm:$src), addr:$dst)]>, OpSize;
495 def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src),
496 "mov{l} {$src, $dst|$dst, $src}",
497 [(store (i32 imm:$src), addr:$dst)]>;
499 def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src),
500 "mov{b} {$src, $dst|$dst, $src}",
501 [(set R8:$dst, (load addr:$src))]>;
502 def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src),
503 "mov{w} {$src, $dst|$dst, $src}",
504 [(set R16:$dst, (load addr:$src))]>, OpSize;
505 def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src),
506 "mov{l} {$src, $dst|$dst, $src}",
507 [(set R32:$dst, (load addr:$src))]>;
509 def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src),
510 "mov{b} {$src, $dst|$dst, $src}",
511 [(store R8:$src, addr:$dst)]>;
512 def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16:$src),
513 "mov{w} {$src, $dst|$dst, $src}",
514 [(store R16:$src, addr:$dst)]>, OpSize;
515 def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src),
516 "mov{l} {$src, $dst|$dst, $src}",
517 [(store R32:$src, addr:$dst)]>;
519 //===----------------------------------------------------------------------===//
520 // Fixed-Register Multiplication and Division Instructions...
523 // Extra precision multiplication
524 def MUL8r : I<0xF6, MRM4r, (ops R8:$src), "mul{b} $src", []>,
525 Imp<[AL],[AX]>; // AL,AH = AL*R8
526 def MUL16r : I<0xF7, MRM4r, (ops R16:$src), "mul{w} $src", []>,
527 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
528 def MUL32r : I<0xF7, MRM4r, (ops R32:$src), "mul{l} $src", []>,
529 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
530 def MUL8m : I<0xF6, MRM4m, (ops i8mem :$src),
531 "mul{b} $src", []>, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
532 def MUL16m : I<0xF7, MRM4m, (ops i16mem:$src),
533 "mul{w} $src", []>, Imp<[AX],[AX,DX]>,
534 OpSize; // AX,DX = AX*[mem16]
535 def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src),
536 "mul{l} $src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
538 def IMUL8r : I<0xF6, MRM5r, (ops R8:$src), "imul{b} $src", []>,
539 Imp<[AL],[AX]>; // AL,AH = AL*R8
540 def IMUL16r : I<0xF7, MRM5r, (ops R16:$src), "imul{w} $src", []>,
541 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
542 def IMUL32r : I<0xF7, MRM5r, (ops R32:$src), "imul{l} $src", []>,
543 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
544 def IMUL8m : I<0xF6, MRM5m, (ops i8mem :$src),
545 "imul{b} $src", []>, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
546 def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src),
547 "imul{w} $src", []>, Imp<[AX],[AX,DX]>,
548 OpSize; // AX,DX = AX*[mem16]
549 def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src),
551 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
553 // unsigned division/remainder
554 def DIV8r : I<0xF6, MRM6r, (ops R8:$src), // AX/r8 = AL,AH
555 "div{b} $src", []>, Imp<[AX],[AX]>;
556 def DIV16r : I<0xF7, MRM6r, (ops R16:$src), // DX:AX/r16 = AX,DX
557 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
558 def DIV32r : I<0xF7, MRM6r, (ops R32:$src), // EDX:EAX/r32 = EAX,EDX
559 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
560 def DIV8m : I<0xF6, MRM6m, (ops i8mem:$src), // AX/[mem8] = AL,AH
561 "div{b} $src", []>, Imp<[AX],[AX]>;
562 def DIV16m : I<0xF7, MRM6m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
563 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
564 def DIV32m : I<0xF7, MRM6m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
565 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
567 // Signed division/remainder.
568 def IDIV8r : I<0xF6, MRM7r, (ops R8:$src), // AX/r8 = AL,AH
569 "idiv{b} $src", []>, Imp<[AX],[AX]>;
570 def IDIV16r: I<0xF7, MRM7r, (ops R16:$src), // DX:AX/r16 = AX,DX
571 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
572 def IDIV32r: I<0xF7, MRM7r, (ops R32:$src), // EDX:EAX/r32 = EAX,EDX
573 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
574 def IDIV8m : I<0xF6, MRM7m, (ops i8mem:$src), // AX/[mem8] = AL,AH
575 "idiv{b} $src", []>, Imp<[AX],[AX]>;
576 def IDIV16m: I<0xF7, MRM7m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
577 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
578 def IDIV32m: I<0xF7, MRM7m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
579 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
581 // Sign-extenders for division.
582 def CBW : I<0x98, RawFrm, (ops),
583 "{cbtw|cbw}", []>, Imp<[AL],[AH]>; // AX = signext(AL)
584 def CWD : I<0x99, RawFrm, (ops),
585 "{cwtd|cwd}", []>, Imp<[AX],[DX]>; // DX:AX = signext(AX)
586 def CDQ : I<0x99, RawFrm, (ops),
587 "{cltd|cdq}", []>, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
590 //===----------------------------------------------------------------------===//
591 // Two address Instructions...
593 let isTwoAddress = 1 in {
596 def CMOVB16rr : I<0x42, MRMSrcReg, // if <u, R16 = R16
597 (ops R16:$dst, R16:$src1, R16:$src2),
598 "cmovb {$src2, $dst|$dst, $src2}",
599 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
601 Imp<[STATUS],[]>, TB, OpSize;
602 def CMOVB16rm : I<0x42, MRMSrcMem, // if <u, R16 = [mem16]
603 (ops R16:$dst, R16:$src1, i16mem:$src2),
604 "cmovb {$src2, $dst|$dst, $src2}",
605 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
607 Imp<[STATUS],[]>, TB, OpSize;
608 def CMOVB32rr : I<0x42, MRMSrcReg, // if <u, R32 = R32
609 (ops R32:$dst, R32:$src1, R32:$src2),
610 "cmovb {$src2, $dst|$dst, $src2}",
611 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
613 Imp<[STATUS],[]>, TB;
614 def CMOVB32rm : I<0x42, MRMSrcMem, // if <u, R32 = [mem32]
615 (ops R32:$dst, R32:$src1, i32mem:$src2),
616 "cmovb {$src2, $dst|$dst, $src2}",
617 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
619 Imp<[STATUS],[]>, TB;
621 def CMOVAE16rr: I<0x43, MRMSrcReg, // if >=u, R16 = R16
622 (ops R16:$dst, R16:$src1, R16:$src2),
623 "cmovae {$src2, $dst|$dst, $src2}",
624 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
626 Imp<[STATUS],[]>, TB, OpSize;
627 def CMOVAE16rm: I<0x43, MRMSrcMem, // if >=u, R16 = [mem16]
628 (ops R16:$dst, R16:$src1, i16mem:$src2),
629 "cmovae {$src2, $dst|$dst, $src2}",
630 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
632 Imp<[STATUS],[]>, TB, OpSize;
633 def CMOVAE32rr: I<0x43, MRMSrcReg, // if >=u, R32 = R32
634 (ops R32:$dst, R32:$src1, R32:$src2),
635 "cmovae {$src2, $dst|$dst, $src2}",
636 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
638 Imp<[STATUS],[]>, TB;
639 def CMOVAE32rm: I<0x43, MRMSrcMem, // if >=u, R32 = [mem32]
640 (ops R32:$dst, R32:$src1, i32mem:$src2),
641 "cmovae {$src2, $dst|$dst, $src2}",
642 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
644 Imp<[STATUS],[]>, TB;
646 def CMOVE16rr : I<0x44, MRMSrcReg, // if ==, R16 = R16
647 (ops R16:$dst, R16:$src1, R16:$src2),
648 "cmove {$src2, $dst|$dst, $src2}",
649 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
651 Imp<[STATUS],[]>, TB, OpSize;
652 def CMOVE16rm : I<0x44, MRMSrcMem, // if ==, R16 = [mem16]
653 (ops R16:$dst, R16:$src1, i16mem:$src2),
654 "cmove {$src2, $dst|$dst, $src2}",
655 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
657 Imp<[STATUS],[]>, TB, OpSize;
658 def CMOVE32rr : I<0x44, MRMSrcReg, // if ==, R32 = R32
659 (ops R32:$dst, R32:$src1, R32:$src2),
660 "cmove {$src2, $dst|$dst, $src2}",
661 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
663 Imp<[STATUS],[]>, TB;
664 def CMOVE32rm : I<0x44, MRMSrcMem, // if ==, R32 = [mem32]
665 (ops R32:$dst, R32:$src1, i32mem:$src2),
666 "cmove {$src2, $dst|$dst, $src2}",
667 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
669 Imp<[STATUS],[]>, TB;
671 def CMOVNE16rr: I<0x45, MRMSrcReg, // if !=, R16 = R16
672 (ops R16:$dst, R16:$src1, R16:$src2),
673 "cmovne {$src2, $dst|$dst, $src2}",
674 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
676 Imp<[STATUS],[]>, TB, OpSize;
677 def CMOVNE16rm: I<0x45, MRMSrcMem, // if !=, R16 = [mem16]
678 (ops R16:$dst, R16:$src1, i16mem:$src2),
679 "cmovne {$src2, $dst|$dst, $src2}",
680 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
682 Imp<[STATUS],[]>, TB, OpSize;
683 def CMOVNE32rr: I<0x45, MRMSrcReg, // if !=, R32 = R32
684 (ops R32:$dst, R32:$src1, R32:$src2),
685 "cmovne {$src2, $dst|$dst, $src2}",
686 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
688 Imp<[STATUS],[]>, TB;
689 def CMOVNE32rm: I<0x45, MRMSrcMem, // if !=, R32 = [mem32]
690 (ops R32:$dst, R32:$src1, i32mem:$src2),
691 "cmovne {$src2, $dst|$dst, $src2}",
692 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
694 Imp<[STATUS],[]>, TB;
696 def CMOVBE16rr: I<0x46, MRMSrcReg, // if <=u, R16 = R16
697 (ops R16:$dst, R16:$src1, R16:$src2),
698 "cmovbe {$src2, $dst|$dst, $src2}",
699 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
701 Imp<[STATUS],[]>, TB, OpSize;
702 def CMOVBE16rm: I<0x46, MRMSrcMem, // if <=u, R16 = [mem16]
703 (ops R16:$dst, R16:$src1, i16mem:$src2),
704 "cmovbe {$src2, $dst|$dst, $src2}",
705 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
707 Imp<[STATUS],[]>, TB, OpSize;
708 def CMOVBE32rr: I<0x46, MRMSrcReg, // if <=u, R32 = R32
709 (ops R32:$dst, R32:$src1, R32:$src2),
710 "cmovbe {$src2, $dst|$dst, $src2}",
711 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
713 Imp<[STATUS],[]>, TB;
714 def CMOVBE32rm: I<0x46, MRMSrcMem, // if <=u, R32 = [mem32]
715 (ops R32:$dst, R32:$src1, i32mem:$src2),
716 "cmovbe {$src2, $dst|$dst, $src2}",
717 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
719 Imp<[STATUS],[]>, TB;
721 def CMOVA16rr : I<0x47, MRMSrcReg, // if >u, R16 = R16
722 (ops R16:$dst, R16:$src1, R16:$src2),
723 "cmova {$src2, $dst|$dst, $src2}",
724 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
726 Imp<[STATUS],[]>, TB, OpSize;
727 def CMOVA16rm : I<0x47, MRMSrcMem, // if >u, R16 = [mem16]
728 (ops R16:$dst, R16:$src1, i16mem:$src2),
729 "cmova {$src2, $dst|$dst, $src2}",
730 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
732 Imp<[STATUS],[]>, TB, OpSize;
733 def CMOVA32rr : I<0x47, MRMSrcReg, // if >u, R32 = R32
734 (ops R32:$dst, R32:$src1, R32:$src2),
735 "cmova {$src2, $dst|$dst, $src2}",
736 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
738 Imp<[STATUS],[]>, TB;
739 def CMOVA32rm : I<0x47, MRMSrcMem, // if >u, R32 = [mem32]
740 (ops R32:$dst, R32:$src1, i32mem:$src2),
741 "cmova {$src2, $dst|$dst, $src2}",
742 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
744 Imp<[STATUS],[]>, TB;
746 def CMOVL16rr : I<0x4C, MRMSrcReg, // if <s, R16 = R16
747 (ops R16:$dst, R16:$src1, R16:$src2),
748 "cmovl {$src2, $dst|$dst, $src2}",
749 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
751 Imp<[STATUS],[]>, TB, OpSize;
752 def CMOVL16rm : I<0x4C, MRMSrcMem, // if <s, R16 = [mem16]
753 (ops R16:$dst, R16:$src1, i16mem:$src2),
754 "cmovl {$src2, $dst|$dst, $src2}",
755 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
757 Imp<[STATUS],[]>, TB, OpSize;
758 def CMOVL32rr : I<0x4C, MRMSrcReg, // if <s, R32 = R32
759 (ops R32:$dst, R32:$src1, R32:$src2),
760 "cmovl {$src2, $dst|$dst, $src2}",
761 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
763 Imp<[STATUS],[]>, TB;
764 def CMOVL32rm : I<0x4C, MRMSrcMem, // if <s, R32 = [mem32]
765 (ops R32:$dst, R32:$src1, i32mem:$src2),
766 "cmovl {$src2, $dst|$dst, $src2}",
767 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
769 Imp<[STATUS],[]>, TB;
771 def CMOVGE16rr: I<0x4D, MRMSrcReg, // if >=s, R16 = R16
772 (ops R16:$dst, R16:$src1, R16:$src2),
773 "cmovge {$src2, $dst|$dst, $src2}",
774 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
776 Imp<[STATUS],[]>, TB, OpSize;
777 def CMOVGE16rm: I<0x4D, MRMSrcMem, // if >=s, R16 = [mem16]
778 (ops R16:$dst, R16:$src1, i16mem:$src2),
779 "cmovge {$src2, $dst|$dst, $src2}",
780 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
782 Imp<[STATUS],[]>, TB, OpSize;
783 def CMOVGE32rr: I<0x4D, MRMSrcReg, // if >=s, R32 = R32
784 (ops R32:$dst, R32:$src1, R32:$src2),
785 "cmovge {$src2, $dst|$dst, $src2}",
786 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
788 Imp<[STATUS],[]>, TB;
789 def CMOVGE32rm: I<0x4D, MRMSrcMem, // if >=s, R32 = [mem32]
790 (ops R32:$dst, R32:$src1, i32mem:$src2),
791 "cmovge {$src2, $dst|$dst, $src2}",
792 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
794 Imp<[STATUS],[]>, TB;
796 def CMOVLE16rr: I<0x4E, MRMSrcReg, // if <=s, R16 = R16
797 (ops R16:$dst, R16:$src1, R16:$src2),
798 "cmovle {$src2, $dst|$dst, $src2}",
799 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
801 Imp<[STATUS],[]>, TB, OpSize;
802 def CMOVLE16rm: I<0x4E, MRMSrcMem, // if <=s, R16 = [mem16]
803 (ops R16:$dst, R16:$src1, i16mem:$src2),
804 "cmovle {$src2, $dst|$dst, $src2}",
805 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
807 Imp<[STATUS],[]>, TB, OpSize;
808 def CMOVLE32rr: I<0x4E, MRMSrcReg, // if <=s, R32 = R32
809 (ops R32:$dst, R32:$src1, R32:$src2),
810 "cmovle {$src2, $dst|$dst, $src2}",
811 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
813 Imp<[STATUS],[]>, TB;
814 def CMOVLE32rm: I<0x4E, MRMSrcMem, // if <=s, R32 = [mem32]
815 (ops R32:$dst, R32:$src1, i32mem:$src2),
816 "cmovle {$src2, $dst|$dst, $src2}",
817 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
819 Imp<[STATUS],[]>, TB;
821 def CMOVG16rr : I<0x4F, MRMSrcReg, // if >s, R16 = R16
822 (ops R16:$dst, R16:$src1, R16:$src2),
823 "cmovg {$src2, $dst|$dst, $src2}",
824 [(set R16:$dst, (X86cmov R16:$src1, R16:$src2,
826 Imp<[STATUS],[]>, TB, OpSize;
827 def CMOVG16rm : I<0x4F, MRMSrcMem, // if >s, R16 = [mem16]
828 (ops R16:$dst, R16:$src1, i16mem:$src2),
829 "cmovg {$src2, $dst|$dst, $src2}",
830 [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2),
832 Imp<[STATUS],[]>, TB, OpSize;
833 def CMOVG32rr : I<0x4F, MRMSrcReg, // if >s, R32 = R32
834 (ops R32:$dst, R32:$src1, R32:$src2),
835 "cmovg {$src2, $dst|$dst, $src2}",
836 [(set R32:$dst, (X86cmov R32:$src1, R32:$src2,
838 Imp<[STATUS],[]>, TB;
839 def CMOVG32rm : I<0x4F, MRMSrcMem, // if >s, R32 = [mem32]
840 (ops R32:$dst, R32:$src1, i32mem:$src2),
841 "cmovg {$src2, $dst|$dst, $src2}",
842 [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2),
844 Imp<[STATUS],[]>, TB;
846 def CMOVS16rr : I<0x48, MRMSrcReg, // if signed, R16 = R16
847 (ops R16:$dst, R16:$src1, R16:$src2),
848 "cmovs {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
849 def CMOVS16rm : I<0x48, MRMSrcMem, // if signed, R16 = [mem16]
850 (ops R16:$dst, R16:$src1, i16mem:$src2),
851 "cmovs {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
852 def CMOVS32rr : I<0x48, MRMSrcReg, // if signed, R32 = R32
853 (ops R32:$dst, R32:$src1, R32:$src2),
854 "cmovs {$src2, $dst|$dst, $src2}", []>, TB;
855 def CMOVS32rm : I<0x48, MRMSrcMem, // if signed, R32 = [mem32]
856 (ops R32:$dst, R32:$src1, i32mem:$src2),
857 "cmovs {$src2, $dst|$dst, $src2}", []>, TB;
859 def CMOVNS16rr: I<0x49, MRMSrcReg, // if !signed, R16 = R16
860 (ops R16:$dst, R16:$src1, R16:$src2),
861 "cmovns {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
862 def CMOVNS16rm: I<0x49, MRMSrcMem, // if !signed, R16 = [mem16]
863 (ops R16:$dst, R16:$src1, i16mem:$src2),
864 "cmovns {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
865 def CMOVNS32rr: I<0x49, MRMSrcReg, // if !signed, R32 = R32
866 (ops R32:$dst, R32:$src1, R32:$src2),
867 "cmovns {$src2, $dst|$dst, $src2}", []>, TB;
868 def CMOVNS32rm: I<0x49, MRMSrcMem, // if !signed, R32 = [mem32]
869 (ops R32:$dst, R32:$src1, i32mem:$src2),
870 "cmovns {$src2, $dst|$dst, $src2}", []>, TB;
872 def CMOVP16rr : I<0x4A, MRMSrcReg, // if parity, R16 = R16
873 (ops R16:$dst, R16:$src1, R16:$src2),
874 "cmovp {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
875 def CMOVP16rm : I<0x4A, MRMSrcMem, // if parity, R16 = [mem16]
876 (ops R16:$dst, R16:$src1, i16mem:$src2),
877 "cmovp {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
878 def CMOVP32rr : I<0x4A, MRMSrcReg, // if parity, R32 = R32
879 (ops R32:$dst, R32:$src1, R32:$src2),
880 "cmovp {$src2, $dst|$dst, $src2}", []>, TB;
881 def CMOVP32rm : I<0x4A, MRMSrcMem, // if parity, R32 = [mem32]
882 (ops R32:$dst, R32:$src1, i32mem:$src2),
883 "cmovp {$src2, $dst|$dst, $src2}", []>, TB;
885 def CMOVNP16rr : I<0x4B, MRMSrcReg, // if !parity, R16 = R16
886 (ops R16:$dst, R16:$src1, R16:$src2),
887 "cmovnp {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
888 def CMOVNP16rm : I<0x4B, MRMSrcMem, // if !parity, R16 = [mem16]
889 (ops R16:$dst, R16:$src1, i16mem:$src2),
890 "cmovnp {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
891 def CMOVNP32rr : I<0x4B, MRMSrcReg, // if !parity, R32 = R32
892 (ops R32:$dst, R32:$src1, R32:$src2),
893 "cmovnp {$src2, $dst|$dst, $src2}", []>, TB;
894 def CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, R32 = [mem32]
895 (ops R32:$dst, R32:$src1, i32mem:$src2),
896 "cmovnp {$src2, $dst|$dst, $src2}", []>, TB;
899 // unary instructions
900 def NEG8r : I<0xF6, MRM3r, (ops R8 :$dst, R8 :$src), "neg{b} $dst",
901 [(set R8:$dst, (ineg R8:$src))]>;
902 def NEG16r : I<0xF7, MRM3r, (ops R16:$dst, R16:$src), "neg{w} $dst",
903 [(set R16:$dst, (ineg R16:$src))]>, OpSize;
904 def NEG32r : I<0xF7, MRM3r, (ops R32:$dst, R32:$src), "neg{l} $dst",
905 [(set R32:$dst, (ineg R32:$src))]>;
906 let isTwoAddress = 0 in {
907 def NEG8m : I<0xF6, MRM3m, (ops i8mem :$dst), "neg{b} $dst",
908 [(store (ineg (loadi8 addr:$dst)), addr:$dst)]>;
909 def NEG16m : I<0xF7, MRM3m, (ops i16mem:$dst), "neg{w} $dst",
910 [(store (ineg (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
911 def NEG32m : I<0xF7, MRM3m, (ops i32mem:$dst), "neg{l} $dst",
912 [(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
916 def NOT8r : I<0xF6, MRM2r, (ops R8 :$dst, R8 :$src), "not{b} $dst",
917 [(set R8:$dst, (not R8:$src))]>;
918 def NOT16r : I<0xF7, MRM2r, (ops R16:$dst, R16:$src), "not{w} $dst",
919 [(set R16:$dst, (not R16:$src))]>, OpSize;
920 def NOT32r : I<0xF7, MRM2r, (ops R32:$dst, R32:$src), "not{l} $dst",
921 [(set R32:$dst, (not R32:$src))]>;
922 let isTwoAddress = 0 in {
923 def NOT8m : I<0xF6, MRM2m, (ops i8mem :$dst), "not{b} $dst",
924 [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
925 def NOT16m : I<0xF7, MRM2m, (ops i16mem:$dst), "not{w} $dst",
926 [(store (not (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
927 def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst",
928 [(store (not (loadi32 addr:$dst)), addr:$dst)]>;
931 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
932 def INC8r : I<0xFE, MRM0r, (ops R8 :$dst, R8 :$src), "inc{b} $dst",
933 [(set R8:$dst, (add R8:$src, 1))]>;
934 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
935 def INC16r : I<0xFF, MRM0r, (ops R16:$dst, R16:$src), "inc{w} $dst",
936 [(set R16:$dst, (add R16:$src, 1))]>, OpSize;
937 def INC32r : I<0xFF, MRM0r, (ops R32:$dst, R32:$src), "inc{l} $dst",
938 [(set R32:$dst, (add R32:$src, 1))]>;
940 let isTwoAddress = 0 in {
941 def INC8m : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
942 [(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
943 def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
944 [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
945 def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
946 [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
949 def DEC8r : I<0xFE, MRM1r, (ops R8 :$dst, R8 :$src), "dec{b} $dst",
950 [(set R8:$dst, (add R8:$src, -1))]>;
951 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
952 def DEC16r : I<0xFF, MRM1r, (ops R16:$dst, R16:$src), "dec{w} $dst",
953 [(set R16:$dst, (add R16:$src, -1))]>, OpSize;
954 def DEC32r : I<0xFF, MRM1r, (ops R32:$dst, R32:$src), "dec{l} $dst",
955 [(set R32:$dst, (add R32:$src, -1))]>;
958 let isTwoAddress = 0 in {
959 def DEC8m : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
960 [(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
961 def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
962 [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
963 def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
964 [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
967 // Logical operators...
968 let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y
969 def AND8rr : I<0x20, MRMDestReg,
970 (ops R8 :$dst, R8 :$src1, R8 :$src2),
971 "and{b} {$src2, $dst|$dst, $src2}",
972 [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
973 def AND16rr : I<0x21, MRMDestReg,
974 (ops R16:$dst, R16:$src1, R16:$src2),
975 "and{w} {$src2, $dst|$dst, $src2}",
976 [(set R16:$dst, (and R16:$src1, R16:$src2))]>, OpSize;
977 def AND32rr : I<0x21, MRMDestReg,
978 (ops R32:$dst, R32:$src1, R32:$src2),
979 "and{l} {$src2, $dst|$dst, $src2}",
980 [(set R32:$dst, (and R32:$src1, R32:$src2))]>;
983 def AND8rm : I<0x22, MRMSrcMem,
984 (ops R8 :$dst, R8 :$src1, i8mem :$src2),
985 "and{b} {$src2, $dst|$dst, $src2}",
986 [(set R8:$dst, (and R8:$src1, (load addr:$src2)))]>;
987 def AND16rm : I<0x23, MRMSrcMem,
988 (ops R16:$dst, R16:$src1, i16mem:$src2),
989 "and{w} {$src2, $dst|$dst, $src2}",
990 [(set R16:$dst, (and R16:$src1, (load addr:$src2)))]>, OpSize;
991 def AND32rm : I<0x23, MRMSrcMem,
992 (ops R32:$dst, R32:$src1, i32mem:$src2),
993 "and{l} {$src2, $dst|$dst, $src2}",
994 [(set R32:$dst, (and R32:$src1, (load addr:$src2)))]>;
996 def AND8ri : Ii8<0x80, MRM4r,
997 (ops R8 :$dst, R8 :$src1, i8imm :$src2),
998 "and{b} {$src2, $dst|$dst, $src2}",
999 [(set R8:$dst, (and R8:$src1, imm:$src2))]>;
1000 def AND16ri : Ii16<0x81, MRM4r,
1001 (ops R16:$dst, R16:$src1, i16imm:$src2),
1002 "and{w} {$src2, $dst|$dst, $src2}",
1003 [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize;
1004 def AND32ri : Ii32<0x81, MRM4r,
1005 (ops R32:$dst, R32:$src1, i32imm:$src2),
1006 "and{l} {$src2, $dst|$dst, $src2}",
1007 [(set R32:$dst, (and R32:$src1, imm:$src2))]>;
1008 def AND16ri8 : Ii8<0x83, MRM4r,
1009 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1010 "and{w} {$src2, $dst|$dst, $src2}",
1011 [(set R16:$dst, (and R16:$src1, i16immSExt8:$src2))]>,
1013 def AND32ri8 : Ii8<0x83, MRM4r,
1014 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1015 "and{l} {$src2, $dst|$dst, $src2}",
1016 [(set R32:$dst, (and R32:$src1, i32immSExt8:$src2))]>;
1018 let isTwoAddress = 0 in {
1019 def AND8mr : I<0x20, MRMDestMem,
1020 (ops i8mem :$dst, R8 :$src),
1021 "and{b} {$src, $dst|$dst, $src}",
1022 [(store (and (load addr:$dst), R8:$src), addr:$dst)]>;
1023 def AND16mr : I<0x21, MRMDestMem,
1024 (ops i16mem:$dst, R16:$src),
1025 "and{w} {$src, $dst|$dst, $src}",
1026 [(store (and (load addr:$dst), R16:$src), addr:$dst)]>,
1028 def AND32mr : I<0x21, MRMDestMem,
1029 (ops i32mem:$dst, R32:$src),
1030 "and{l} {$src, $dst|$dst, $src}",
1031 [(store (and (load addr:$dst), R32:$src), addr:$dst)]>;
1032 def AND8mi : Ii8<0x80, MRM4m,
1033 (ops i8mem :$dst, i8imm :$src),
1034 "and{b} {$src, $dst|$dst, $src}",
1035 [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1036 def AND16mi : Ii16<0x81, MRM4m,
1037 (ops i16mem:$dst, i16imm:$src),
1038 "and{w} {$src, $dst|$dst, $src}",
1039 [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1041 def AND32mi : Ii32<0x81, MRM4m,
1042 (ops i32mem:$dst, i32imm:$src),
1043 "and{l} {$src, $dst|$dst, $src}",
1044 [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1045 def AND16mi8 : Ii8<0x83, MRM4m,
1046 (ops i16mem:$dst, i16i8imm :$src),
1047 "and{w} {$src, $dst|$dst, $src}",
1048 [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1050 def AND32mi8 : Ii8<0x83, MRM4m,
1051 (ops i32mem:$dst, i32i8imm :$src),
1052 "and{l} {$src, $dst|$dst, $src}",
1053 [(store (add (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1057 let isCommutable = 1 in { // X = OR Y, Z --> X = OR Z, Y
1058 def OR8rr : I<0x08, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1059 "or{b} {$src2, $dst|$dst, $src2}",
1060 [(set R8:$dst, (or R8:$src1, R8:$src2))]>;
1061 def OR16rr : I<0x09, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1062 "or{w} {$src2, $dst|$dst, $src2}",
1063 [(set R16:$dst, (or R16:$src1, R16:$src2))]>, OpSize;
1064 def OR32rr : I<0x09, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1065 "or{l} {$src2, $dst|$dst, $src2}",
1066 [(set R32:$dst, (or R32:$src1, R32:$src2))]>;
1068 def OR8rm : I<0x0A, MRMSrcMem , (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1069 "or{b} {$src2, $dst|$dst, $src2}",
1070 [(set R8:$dst, (or R8:$src1, (load addr:$src2)))]>;
1071 def OR16rm : I<0x0B, MRMSrcMem , (ops R16:$dst, R16:$src1, i16mem:$src2),
1072 "or{w} {$src2, $dst|$dst, $src2}",
1073 [(set R16:$dst, (or R16:$src1, (load addr:$src2)))]>, OpSize;
1074 def OR32rm : I<0x0B, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1075 "or{l} {$src2, $dst|$dst, $src2}",
1076 [(set R32:$dst, (or R32:$src1, (load addr:$src2)))]>;
1078 def OR8ri : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1079 "or{b} {$src2, $dst|$dst, $src2}",
1080 [(set R8:$dst, (or R8:$src1, imm:$src2))]>;
1081 def OR16ri : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1082 "or{w} {$src2, $dst|$dst, $src2}",
1083 [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize;
1084 def OR32ri : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1085 "or{l} {$src2, $dst|$dst, $src2}",
1086 [(set R32:$dst, (or R32:$src1, imm:$src2))]>;
1088 def OR16ri8 : Ii8<0x83, MRM1r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1089 "or{w} {$src2, $dst|$dst, $src2}",
1090 [(set R16:$dst, (or R16:$src1, i16immSExt8:$src2))]>, OpSize;
1091 def OR32ri8 : Ii8<0x83, MRM1r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1092 "or{l} {$src2, $dst|$dst, $src2}",
1093 [(set R32:$dst, (or R32:$src1, i32immSExt8:$src2))]>;
1094 let isTwoAddress = 0 in {
1095 def OR8mr : I<0x08, MRMDestMem, (ops i8mem:$dst, R8:$src),
1096 "or{b} {$src, $dst|$dst, $src}",
1097 [(store (or (load addr:$dst), R8:$src), addr:$dst)]>;
1098 def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, R16:$src),
1099 "or{w} {$src, $dst|$dst, $src}",
1100 [(store (or (load addr:$dst), R16:$src), addr:$dst)]>, OpSize;
1101 def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, R32:$src),
1102 "or{l} {$src, $dst|$dst, $src}",
1103 [(store (or (load addr:$dst), R32:$src), addr:$dst)]>;
1104 def OR8mi : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
1105 "or{b} {$src, $dst|$dst, $src}",
1106 [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1107 def OR16mi : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
1108 "or{w} {$src, $dst|$dst, $src}",
1109 [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1111 def OR32mi : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
1112 "or{l} {$src, $dst|$dst, $src}",
1113 [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1114 def OR16mi8 : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
1115 "or{w} {$src, $dst|$dst, $src}",
1116 [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1118 def OR32mi8 : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
1119 "or{l} {$src, $dst|$dst, $src}",
1120 [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1124 let isCommutable = 1 in { // X = XOR Y, Z --> X = XOR Z, Y
1125 def XOR8rr : I<0x30, MRMDestReg,
1126 (ops R8 :$dst, R8 :$src1, R8 :$src2),
1127 "xor{b} {$src2, $dst|$dst, $src2}",
1128 [(set R8:$dst, (xor R8:$src1, R8:$src2))]>;
1129 def XOR16rr : I<0x31, MRMDestReg,
1130 (ops R16:$dst, R16:$src1, R16:$src2),
1131 "xor{w} {$src2, $dst|$dst, $src2}",
1132 [(set R16:$dst, (xor R16:$src1, R16:$src2))]>, OpSize;
1133 def XOR32rr : I<0x31, MRMDestReg,
1134 (ops R32:$dst, R32:$src1, R32:$src2),
1135 "xor{l} {$src2, $dst|$dst, $src2}",
1136 [(set R32:$dst, (xor R32:$src1, R32:$src2))]>;
1139 def XOR8rm : I<0x32, MRMSrcMem ,
1140 (ops R8 :$dst, R8:$src1, i8mem :$src2),
1141 "xor{b} {$src2, $dst|$dst, $src2}",
1142 [(set R8:$dst, (xor R8:$src1, (load addr:$src2)))]>;
1143 def XOR16rm : I<0x33, MRMSrcMem ,
1144 (ops R16:$dst, R16:$src1, i16mem:$src2),
1145 "xor{w} {$src2, $dst|$dst, $src2}",
1146 [(set R16:$dst, (xor R16:$src1, (load addr:$src2)))]>, OpSize;
1147 def XOR32rm : I<0x33, MRMSrcMem ,
1148 (ops R32:$dst, R32:$src1, i32mem:$src2),
1149 "xor{l} {$src2, $dst|$dst, $src2}",
1150 [(set R32:$dst, (xor R32:$src1, (load addr:$src2)))]>;
1152 def XOR8ri : Ii8<0x80, MRM6r,
1153 (ops R8:$dst, R8:$src1, i8imm:$src2),
1154 "xor{b} {$src2, $dst|$dst, $src2}",
1155 [(set R8:$dst, (xor R8:$src1, imm:$src2))]>;
1156 def XOR16ri : Ii16<0x81, MRM6r,
1157 (ops R16:$dst, R16:$src1, i16imm:$src2),
1158 "xor{w} {$src2, $dst|$dst, $src2}",
1159 [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize;
1160 def XOR32ri : Ii32<0x81, MRM6r,
1161 (ops R32:$dst, R32:$src1, i32imm:$src2),
1162 "xor{l} {$src2, $dst|$dst, $src2}",
1163 [(set R32:$dst, (xor R32:$src1, imm:$src2))]>;
1164 def XOR16ri8 : Ii8<0x83, MRM6r,
1165 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1166 "xor{w} {$src2, $dst|$dst, $src2}",
1167 [(set R16:$dst, (xor R16:$src1, i16immSExt8:$src2))]>,
1169 def XOR32ri8 : Ii8<0x83, MRM6r,
1170 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1171 "xor{l} {$src2, $dst|$dst, $src2}",
1172 [(set R32:$dst, (xor R32:$src1, i32immSExt8:$src2))]>;
1173 let isTwoAddress = 0 in {
1174 def XOR8mr : I<0x30, MRMDestMem,
1175 (ops i8mem :$dst, R8 :$src),
1176 "xor{b} {$src, $dst|$dst, $src}",
1177 [(store (xor (load addr:$dst), R8:$src), addr:$dst)]>;
1178 def XOR16mr : I<0x31, MRMDestMem,
1179 (ops i16mem:$dst, R16:$src),
1180 "xor{w} {$src, $dst|$dst, $src}",
1181 [(store (xor (load addr:$dst), R16:$src), addr:$dst)]>,
1183 def XOR32mr : I<0x31, MRMDestMem,
1184 (ops i32mem:$dst, R32:$src),
1185 "xor{l} {$src, $dst|$dst, $src}",
1186 [(store (xor (load addr:$dst), R32:$src), addr:$dst)]>;
1187 def XOR8mi : Ii8<0x80, MRM6m,
1188 (ops i8mem :$dst, i8imm :$src),
1189 "xor{b} {$src, $dst|$dst, $src}",
1190 [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1191 def XOR16mi : Ii16<0x81, MRM6m,
1192 (ops i16mem:$dst, i16imm:$src),
1193 "xor{w} {$src, $dst|$dst, $src}",
1194 [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1196 def XOR32mi : Ii32<0x81, MRM6m,
1197 (ops i32mem:$dst, i32imm:$src),
1198 "xor{l} {$src, $dst|$dst, $src}",
1199 [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1200 def XOR16mi8 : Ii8<0x83, MRM6m,
1201 (ops i16mem:$dst, i16i8imm :$src),
1202 "xor{w} {$src, $dst|$dst, $src}",
1203 [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1205 def XOR32mi8 : Ii8<0x83, MRM6m,
1206 (ops i32mem:$dst, i32i8imm :$src),
1207 "xor{l} {$src, $dst|$dst, $src}",
1208 [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1211 // Shift instructions
1212 // FIXME: provide shorter instructions when imm8 == 1
1213 def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
1214 "shl{b} {%cl, $dst|$dst, %CL}",
1215 [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
1216 def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
1217 "shl{w} {%cl, $dst|$dst, %CL}",
1218 [(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1219 def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
1220 "shl{l} {%cl, $dst|$dst, %CL}",
1221 [(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
1223 def SHL8ri : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1224 "shl{b} {$src2, $dst|$dst, $src2}",
1225 [(set R8:$dst, (shl R8:$src1, (i8 imm:$src2)))]>;
1226 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1227 def SHL16ri : Ii8<0xC1, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1228 "shl{w} {$src2, $dst|$dst, $src2}",
1229 [(set R16:$dst, (shl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1230 def SHL32ri : Ii8<0xC1, MRM4r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1231 "shl{l} {$src2, $dst|$dst, $src2}",
1232 [(set R32:$dst, (shl R32:$src1, (i8 imm:$src2)))]>;
1235 let isTwoAddress = 0 in {
1236 def SHL8mCL : I<0xD2, MRM4m, (ops i8mem :$dst),
1237 "shl{b} {%cl, $dst|$dst, %CL}",
1238 [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
1240 def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
1241 "shl{w} {%cl, $dst|$dst, %CL}",
1242 [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
1243 Imp<[CL],[]>, OpSize;
1244 def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
1245 "shl{l} {%cl, $dst|$dst, %CL}",
1246 [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
1248 def SHL8mi : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
1249 "shl{b} {$src, $dst|$dst, $src}",
1250 [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1251 def SHL16mi : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
1252 "shl{w} {$src, $dst|$dst, $src}",
1253 [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1255 def SHL32mi : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
1256 "shl{l} {$src, $dst|$dst, $src}",
1257 [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1260 def SHR8rCL : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
1261 "shr{b} {%cl, $dst|$dst, %CL}",
1262 [(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
1263 def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
1264 "shr{w} {%cl, $dst|$dst, %CL}",
1265 [(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1266 def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
1267 "shr{l} {%cl, $dst|$dst, %CL}",
1268 [(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
1270 def SHR8ri : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1271 "shr{b} {$src2, $dst|$dst, $src2}",
1272 [(set R8:$dst, (srl R8:$src1, (i8 imm:$src2)))]>;
1273 def SHR16ri : Ii8<0xC1, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1274 "shr{w} {$src2, $dst|$dst, $src2}",
1275 [(set R16:$dst, (srl R16:$src1, (i8 imm:$src2)))]>, OpSize;
1276 def SHR32ri : Ii8<0xC1, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1277 "shr{l} {$src2, $dst|$dst, $src2}",
1278 [(set R32:$dst, (srl R32:$src1, (i8 imm:$src2)))]>;
1280 let isTwoAddress = 0 in {
1281 def SHR8mCL : I<0xD2, MRM5m, (ops i8mem :$dst),
1282 "shr{b} {%cl, $dst|$dst, %CL}",
1283 [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
1285 def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
1286 "shr{w} {%cl, $dst|$dst, %CL}",
1287 [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
1288 Imp<[CL],[]>, OpSize;
1289 def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
1290 "shr{l} {%cl, $dst|$dst, %CL}",
1291 [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
1293 def SHR8mi : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
1294 "shr{b} {$src, $dst|$dst, $src}",
1295 [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1296 def SHR16mi : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
1297 "shr{w} {$src, $dst|$dst, $src}",
1298 [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1300 def SHR32mi : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
1301 "shr{l} {$src, $dst|$dst, $src}",
1302 [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1305 def SAR8rCL : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
1306 "sar{b} {%cl, $dst|$dst, %CL}",
1307 [(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
1308 def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
1309 "sar{w} {%cl, $dst|$dst, %CL}",
1310 [(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1311 def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
1312 "sar{l} {%cl, $dst|$dst, %CL}",
1313 [(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
1315 def SAR8ri : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1316 "sar{b} {$src2, $dst|$dst, $src2}",
1317 [(set R8:$dst, (sra R8:$src1, (i8 imm:$src2)))]>;
1318 def SAR16ri : Ii8<0xC1, MRM7r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1319 "sar{w} {$src2, $dst|$dst, $src2}",
1320 [(set R16:$dst, (sra R16:$src1, (i8 imm:$src2)))]>,
1322 def SAR32ri : Ii8<0xC1, MRM7r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1323 "sar{l} {$src2, $dst|$dst, $src2}",
1324 [(set R32:$dst, (sra R32:$src1, (i8 imm:$src2)))]>;
1325 let isTwoAddress = 0 in {
1326 def SAR8mCL : I<0xD2, MRM7m, (ops i8mem :$dst),
1327 "sar{b} {%cl, $dst|$dst, %CL}",
1328 [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
1330 def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
1331 "sar{w} {%cl, $dst|$dst, %CL}",
1332 [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
1333 Imp<[CL],[]>, OpSize;
1334 def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst),
1335 "sar{l} {%cl, $dst|$dst, %CL}",
1336 [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
1338 def SAR8mi : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
1339 "sar{b} {$src, $dst|$dst, $src}",
1340 [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1341 def SAR16mi : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
1342 "sar{w} {$src, $dst|$dst, $src}",
1343 [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1345 def SAR32mi : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
1346 "sar{l} {$src, $dst|$dst, $src}",
1347 [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1350 // Rotate instructions
1351 // FIXME: provide shorter instructions when imm8 == 1
1352 def ROL8rCL : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src),
1353 "rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1354 def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src),
1355 "rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
1356 def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src),
1357 "rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1359 def ROL8ri : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1360 "rol{b} {$src2, $dst|$dst, $src2}", []>;
1361 def ROL16ri : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1362 "rol{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1363 def ROL32ri : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1364 "rol{l} {$src2, $dst|$dst, $src2}", []>;
1366 let isTwoAddress = 0 in {
1367 def ROL8mCL : I<0xD2, MRM0m, (ops i8mem :$dst),
1368 "rol{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1369 def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
1370 "rol{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
1371 def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
1372 "rol{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1373 def ROL8mi : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
1374 "rol{b} {$src, $dst|$dst, $src}", []>;
1375 def ROL16mi : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
1376 "rol{w} {$src, $dst|$dst, $src}", []>, OpSize;
1377 def ROL32mi : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
1378 "rol{l} {$src, $dst|$dst, $src}", []>;
1381 def ROR8rCL : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src),
1382 "ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1383 def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src),
1384 "ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
1385 def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src),
1386 "ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1388 def ROR8ri : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
1389 "ror{b} {$src2, $dst|$dst, $src2}", []>;
1390 def ROR16ri : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1391 "ror{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1392 def ROR32ri : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1393 "ror{l} {$src2, $dst|$dst, $src2}", []>;
1394 let isTwoAddress = 0 in {
1395 def ROR8mCL : I<0xD2, MRM1m, (ops i8mem :$dst),
1396 "ror{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1397 def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
1398 "ror{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
1399 def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst),
1400 "ror{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
1401 def ROR8mi : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
1402 "ror{b} {$src, $dst|$dst, $src}", []>;
1403 def ROR16mi : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
1404 "ror{w} {$src, $dst|$dst, $src}", []>, OpSize;
1405 def ROR32mi : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
1406 "ror{l} {$src, $dst|$dst, $src}", []>;
1411 // Double shift instructions (generalizations of rotate)
1413 def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1414 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1416 def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1417 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1419 def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1420 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1421 Imp<[CL],[]>, TB, OpSize;
1422 def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1423 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1424 Imp<[CL],[]>, TB, OpSize;
1426 let isCommutable = 1 in { // These instructions commute to each other.
1427 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
1428 (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1429 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
1430 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
1431 (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
1432 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
1433 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
1434 (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1435 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1437 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
1438 (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
1439 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1443 let isTwoAddress = 0 in {
1444 def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1445 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1447 def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1448 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1450 def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
1451 (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1452 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1454 def SHRD32mri8 : Ii8<0xAC, MRMDestMem,
1455 (ops i32mem:$dst, R32:$src2, i8imm:$src3),
1456 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1459 def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1460 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1461 Imp<[CL],[]>, TB, OpSize;
1462 def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1463 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
1464 Imp<[CL],[]>, TB, OpSize;
1465 def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
1466 (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1467 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1469 def SHRD16mri8 : Ii8<0xAC, MRMDestMem,
1470 (ops i16mem:$dst, R16:$src2, i8imm:$src3),
1471 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
1477 let isCommutable = 1 in { // X = ADD Y, Z --> X = ADD Z, Y
1478 def ADD8rr : I<0x00, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1479 "add{b} {$src2, $dst|$dst, $src2}",
1480 [(set R8:$dst, (add R8:$src1, R8:$src2))]>;
1481 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1482 def ADD16rr : I<0x01, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1483 "add{w} {$src2, $dst|$dst, $src2}",
1484 [(set R16:$dst, (add R16:$src1, R16:$src2))]>, OpSize;
1485 def ADD32rr : I<0x01, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1486 "add{l} {$src2, $dst|$dst, $src2}",
1487 [(set R32:$dst, (add R32:$src1, R32:$src2))]>;
1488 } // end isConvertibleToThreeAddress
1489 } // end isCommutable
1490 def ADD8rm : I<0x02, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1491 "add{b} {$src2, $dst|$dst, $src2}",
1492 [(set R8:$dst, (add R8:$src1, (load addr:$src2)))]>;
1493 def ADD16rm : I<0x03, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1494 "add{w} {$src2, $dst|$dst, $src2}",
1495 [(set R16:$dst, (add R16:$src1, (load addr:$src2)))]>, OpSize;
1496 def ADD32rm : I<0x03, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1497 "add{l} {$src2, $dst|$dst, $src2}",
1498 [(set R32:$dst, (add R32:$src1, (load addr:$src2)))]>;
1500 def ADD8ri : Ii8<0x80, MRM0r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1501 "add{b} {$src2, $dst|$dst, $src2}",
1502 [(set R8:$dst, (add R8:$src1, imm:$src2))]>;
1504 let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1505 def ADD16ri : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1506 "add{w} {$src2, $dst|$dst, $src2}",
1507 [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize;
1508 def ADD32ri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1509 "add{l} {$src2, $dst|$dst, $src2}",
1510 [(set R32:$dst, (add R32:$src1, imm:$src2))]>;
1513 // FIXME: move ADD16ri8 above ADD16ri to optimize for space.
1514 def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1515 "add{w} {$src2, $dst|$dst, $src2}",
1516 [(set R16:$dst, (add R16:$src1, i16immSExt8:$src2))]>,
1518 def ADD32ri8 : Ii8<0x83, MRM0r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1519 "add{l} {$src2, $dst|$dst, $src2}",
1520 [(set R32:$dst, (add R32:$src1, i32immSExt8:$src2))]>;
1522 let isTwoAddress = 0 in {
1523 def ADD8mr : I<0x00, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1524 "add{b} {$src2, $dst|$dst, $src2}",
1525 [(store (add (load addr:$dst), R8:$src2), addr:$dst)]>;
1526 def ADD16mr : I<0x01, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1527 "add{w} {$src2, $dst|$dst, $src2}",
1528 [(store (add (load addr:$dst), R16:$src2), addr:$dst)]>,
1530 def ADD32mr : I<0x01, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1531 "add{l} {$src2, $dst|$dst, $src2}",
1532 [(store (add (load addr:$dst), R32:$src2), addr:$dst)]>;
1533 def ADD8mi : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
1534 "add{b} {$src2, $dst|$dst, $src2}",
1535 [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1536 def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
1537 "add{w} {$src2, $dst|$dst, $src2}",
1538 [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1540 def ADD32mi : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
1541 "add{l} {$src2, $dst|$dst, $src2}",
1542 [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1543 def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
1544 "add{w} {$src2, $dst|$dst, $src2}",
1545 [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1547 def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
1548 "add{l} {$src2, $dst|$dst, $src2}",
1549 [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1552 let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y
1553 def ADC32rr : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1554 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1556 def ADC32rm : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
1557 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1558 def ADC32ri : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1559 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1560 def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1561 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1563 let isTwoAddress = 0 in {
1564 def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1565 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1566 def ADC32mi : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
1567 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1568 def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i8imm :$src2),
1569 "adc{l} {$src2, $dst|$dst, $src2}", []>;
1572 def SUB8rr : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
1573 "sub{b} {$src2, $dst|$dst, $src2}",
1574 [(set R8:$dst, (sub R8:$src1, R8:$src2))]>;
1575 def SUB16rr : I<0x29, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
1576 "sub{w} {$src2, $dst|$dst, $src2}",
1577 [(set R16:$dst, (sub R16:$src1, R16:$src2))]>, OpSize;
1578 def SUB32rr : I<0x29, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1579 "sub{l} {$src2, $dst|$dst, $src2}",
1580 [(set R32:$dst, (sub R32:$src1, R32:$src2))]>;
1581 def SUB8rm : I<0x2A, MRMSrcMem, (ops R8 :$dst, R8 :$src1, i8mem :$src2),
1582 "sub{b} {$src2, $dst|$dst, $src2}",
1583 [(set R8:$dst, (sub R8:$src1, (load addr:$src2)))]>;
1584 def SUB16rm : I<0x2B, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1585 "sub{w} {$src2, $dst|$dst, $src2}",
1586 [(set R16:$dst, (sub R16:$src1, (load addr:$src2)))]>, OpSize;
1587 def SUB32rm : I<0x2B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1588 "sub{l} {$src2, $dst|$dst, $src2}",
1589 [(set R32:$dst, (sub R32:$src1, (load addr:$src2)))]>;
1591 def SUB8ri : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1592 "sub{b} {$src2, $dst|$dst, $src2}",
1593 [(set R8:$dst, (sub R8:$src1, imm:$src2))]>;
1594 def SUB16ri : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1595 "sub{w} {$src2, $dst|$dst, $src2}",
1596 [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize;
1597 def SUB32ri : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1598 "sub{l} {$src2, $dst|$dst, $src2}",
1599 [(set R32:$dst, (sub R32:$src1, imm:$src2))]>;
1600 def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1601 "sub{w} {$src2, $dst|$dst, $src2}",
1602 [(set R16:$dst, (sub R16:$src1, i16immSExt8:$src2))]>,
1604 def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1605 "sub{l} {$src2, $dst|$dst, $src2}",
1606 [(set R32:$dst, (sub R32:$src1, i32immSExt8:$src2))]>;
1607 let isTwoAddress = 0 in {
1608 def SUB8mr : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2),
1609 "sub{b} {$src2, $dst|$dst, $src2}",
1610 [(store (sub (load addr:$dst), R8:$src2), addr:$dst)]>;
1611 def SUB16mr : I<0x29, MRMDestMem, (ops i16mem:$dst, R16:$src2),
1612 "sub{w} {$src2, $dst|$dst, $src2}",
1613 [(store (sub (load addr:$dst), R16:$src2), addr:$dst)]>,
1615 def SUB32mr : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1616 "sub{l} {$src2, $dst|$dst, $src2}",
1617 [(store (sub (load addr:$dst), R32:$src2), addr:$dst)]>;
1618 def SUB8mi : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2),
1619 "sub{b} {$src2, $dst|$dst, $src2}",
1620 [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1621 def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2),
1622 "sub{w} {$src2, $dst|$dst, $src2}",
1623 [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1625 def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2),
1626 "sub{l} {$src2, $dst|$dst, $src2}",
1627 [(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1628 def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2),
1629 "sub{w} {$src2, $dst|$dst, $src2}",
1630 [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1632 def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2),
1633 "sub{l} {$src2, $dst|$dst, $src2}",
1634 [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1637 def SBB32rr : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
1638 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1640 let isTwoAddress = 0 in {
1641 def SBB32mr : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2),
1642 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1643 def SBB8mi : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2),
1644 "sbb{b} {$src2, $dst|$dst, $src2}", []>;
1645 def SBB16mi : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2),
1646 "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1647 def SBB32mi : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2),
1648 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1649 def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i8imm :$src2),
1650 "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1651 def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i8imm :$src2),
1652 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1654 def SBB8ri : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
1655 "sbb{b} {$src2, $dst|$dst, $src2}", []>;
1656 def SBB16ri : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
1657 "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1659 def SBB32rm : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1660 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1661 def SBB32ri : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
1662 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1664 def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i8imm:$src2),
1665 "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
1666 def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i8imm:$src2),
1667 "sbb{l} {$src2, $dst|$dst, $src2}", []>;
1669 let isCommutable = 1 in { // X = IMUL Y, Z --> X = IMUL Z, Y
1670 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
1671 "imul{w} {$src2, $dst|$dst, $src2}",
1672 [(set R16:$dst, (mul R16:$src1, R16:$src2))]>, TB, OpSize;
1673 def IMUL32rr : I<0xAF, MRMSrcReg, (ops R32:$dst, R32:$src1, R32:$src2),
1674 "imul{l} {$src2, $dst|$dst, $src2}",
1675 [(set R32:$dst, (mul R32:$src1, R32:$src2))]>, TB;
1677 def IMUL16rm : I<0xAF, MRMSrcMem, (ops R16:$dst, R16:$src1, i16mem:$src2),
1678 "imul{w} {$src2, $dst|$dst, $src2}",
1679 [(set R16:$dst, (mul R16:$src1, (load addr:$src2)))]>,
1681 def IMUL32rm : I<0xAF, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
1682 "imul{l} {$src2, $dst|$dst, $src2}",
1683 [(set R32:$dst, (mul R32:$src1, (load addr:$src2)))]>, TB;
1685 } // end Two Address instructions
1687 // Suprisingly enough, these are not two address instructions!
1688 def IMUL16rri : Ii16<0x69, MRMSrcReg, // R16 = R16*I16
1689 (ops R16:$dst, R16:$src1, i16imm:$src2),
1690 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1691 [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize;
1692 def IMUL32rri : Ii32<0x69, MRMSrcReg, // R32 = R32*I32
1693 (ops R32:$dst, R32:$src1, i32imm:$src2),
1694 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1695 [(set R32:$dst, (mul R32:$src1, imm:$src2))]>;
1696 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // R16 = R16*I8
1697 (ops R16:$dst, R16:$src1, i16i8imm:$src2),
1698 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1699 [(set R16:$dst, (mul R16:$src1, i16immSExt8:$src2))]>,
1701 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // R32 = R32*I8
1702 (ops R32:$dst, R32:$src1, i32i8imm:$src2),
1703 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1704 [(set R32:$dst, (mul R32:$src1, i32immSExt8:$src2))]>;
1706 def IMUL16rmi : Ii16<0x69, MRMSrcMem, // R16 = [mem16]*I16
1707 (ops R16:$dst, i16mem:$src1, i16imm:$src2),
1708 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1709 [(set R16:$dst, (mul (load addr:$src1), imm:$src2))]>,
1711 def IMUL32rmi : Ii32<0x69, MRMSrcMem, // R32 = [mem32]*I32
1712 (ops R32:$dst, i32mem:$src1, i32imm:$src2),
1713 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1714 [(set R32:$dst, (mul (load addr:$src1), imm:$src2))]>;
1715 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // R16 = [mem16]*I8
1716 (ops R16:$dst, i16mem:$src1, i16i8imm :$src2),
1717 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
1718 [(set R16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
1720 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // R32 = [mem32]*I8
1721 (ops R32:$dst, i32mem:$src1, i32i8imm: $src2),
1722 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
1723 [(set R32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
1725 //===----------------------------------------------------------------------===//
1726 // Test instructions are just like AND, except they don't generate a result.
1728 let isCommutable = 1 in { // TEST X, Y --> TEST Y, X
1729 def TEST8rr : I<0x84, MRMDestReg, (ops R8:$src1, R8:$src2),
1730 "test{b} {$src2, $src1|$src1, $src2}",
1731 [(set STATUS, (X86test R8:$src1, R8:$src2))]>,
1733 def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
1734 "test{w} {$src2, $src1|$src1, $src2}",
1735 [(set STATUS, (X86test R16:$src1, R16:$src2))]>,
1736 Imp<[],[STATUS]>, OpSize;
1737 def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
1738 "test{l} {$src2, $src1|$src1, $src2}",
1739 [(set STATUS, (X86test R32:$src1, R32:$src2))]>,
1742 def TEST8mr : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
1743 "test{b} {$src2, $src1|$src1, $src2}",
1744 [(set STATUS, (X86test (loadi8 addr:$src1), R8:$src2))]>,
1746 def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
1747 "test{w} {$src2, $src1|$src1, $src2}",
1748 [(set STATUS, (X86test (loadi16 addr:$src1), R16:$src2))]>,
1749 Imp<[],[STATUS]>, OpSize;
1750 def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
1751 "test{l} {$src2, $src1|$src1, $src2}",
1752 [(set STATUS, (X86test (loadi32 addr:$src1), R32:$src2))]>,
1754 def TEST8rm : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
1755 "test{b} {$src2, $src1|$src1, $src2}",
1756 [(set STATUS, (X86test R8:$src1, (loadi8 addr:$src2)))]>,
1758 def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
1759 "test{w} {$src2, $src1|$src1, $src2}",
1760 [(set STATUS, (X86test R16:$src1, (loadi16 addr:$src2)))]>,
1761 Imp<[],[STATUS]>, OpSize;
1762 def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
1763 "test{l} {$src2, $src1|$src1, $src2}",
1764 [(set STATUS, (X86test R32:$src1, (loadi32 addr:$src2)))]>,
1767 def TEST8ri : Ii8 <0xF6, MRM0r, // flags = R8 & imm8
1768 (ops R8:$src1, i8imm:$src2),
1769 "test{b} {$src2, $src1|$src1, $src2}",
1770 [(set STATUS, (X86test R8:$src1, imm:$src2))]>,
1772 def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16
1773 (ops R16:$src1, i16imm:$src2),
1774 "test{w} {$src2, $src1|$src1, $src2}",
1775 [(set STATUS, (X86test R16:$src1, imm:$src2))]>,
1776 Imp<[],[STATUS]>, OpSize;
1777 def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32
1778 (ops R32:$src1, i32imm:$src2),
1779 "test{l} {$src2, $src1|$src1, $src2}",
1780 [(set STATUS, (X86test R32:$src1, imm:$src2))]>,
1782 def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
1783 (ops i8mem:$src1, i8imm:$src2),
1784 "test{b} {$src2, $src1|$src1, $src2}",
1785 [(set STATUS, (X86test (loadi8 addr:$src1), imm:$src2))]>,
1787 def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
1788 (ops i16mem:$src1, i16imm:$src2),
1789 "test{w} {$src2, $src1|$src1, $src2}",
1790 [(set STATUS, (X86test (loadi16 addr:$src1), imm:$src2))]>,
1791 Imp<[],[STATUS]>, OpSize;
1792 def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
1793 (ops i32mem:$src1, i32imm:$src2),
1794 "test{l} {$src2, $src1|$src1, $src2}",
1795 [(set STATUS, (X86test (loadi32 addr:$src1), imm:$src2))]>,
1799 // Condition code ops, incl. set if equal/not equal/...
1800 def SAHF : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>; // flags = AH
1801 def LAHF : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>; // AH = flags
1803 def SETBr : I<0x92, MRM0r,
1804 (ops R8 :$dst), "setb $dst", []>, TB; // R8 = < unsign
1805 def SETBm : I<0x92, MRM0m,
1806 (ops i8mem:$dst), "setb $dst", []>, TB; // [mem8] = < unsign
1807 def SETAEr : I<0x93, MRM0r,
1808 (ops R8 :$dst), "setae $dst", []>, TB; // R8 = >= unsign
1809 def SETAEm : I<0x93, MRM0m,
1810 (ops i8mem:$dst), "setae $dst", []>, TB; // [mem8] = >= unsign
1811 def SETEr : I<0x94, MRM0r,
1812 (ops R8 :$dst), "sete $dst", []>, TB; // R8 = ==
1813 def SETEm : I<0x94, MRM0m,
1814 (ops i8mem:$dst), "sete $dst", []>, TB; // [mem8] = ==
1815 def SETNEr : I<0x95, MRM0r,
1816 (ops R8 :$dst), "setne $dst", []>, TB; // R8 = !=
1817 def SETNEm : I<0x95, MRM0m,
1818 (ops i8mem:$dst), "setne $dst", []>, TB; // [mem8] = !=
1819 def SETBEr : I<0x96, MRM0r,
1820 (ops R8 :$dst), "setbe $dst", []>, TB; // R8 = <= unsign
1821 def SETBEm : I<0x96, MRM0m,
1822 (ops i8mem:$dst), "setbe $dst", []>, TB; // [mem8] = <= unsign
1823 def SETAr : I<0x97, MRM0r,
1824 (ops R8 :$dst), "seta $dst", []>, TB; // R8 = > signed
1825 def SETAm : I<0x97, MRM0m,
1826 (ops i8mem:$dst), "seta $dst", []>, TB; // [mem8] = > signed
1827 def SETSr : I<0x98, MRM0r,
1828 (ops R8 :$dst), "sets $dst", []>, TB; // R8 = <sign bit>
1829 def SETSm : I<0x98, MRM0m,
1830 (ops i8mem:$dst), "sets $dst", []>, TB; // [mem8] = <sign bit>
1831 def SETNSr : I<0x99, MRM0r,
1832 (ops R8 :$dst), "setns $dst", []>, TB; // R8 = !<sign bit>
1833 def SETNSm : I<0x99, MRM0m,
1834 (ops i8mem:$dst), "setns $dst", []>, TB; // [mem8] = !<sign bit>
1835 def SETPr : I<0x9A, MRM0r,
1836 (ops R8 :$dst), "setp $dst", []>, TB; // R8 = parity
1837 def SETPm : I<0x9A, MRM0m,
1838 (ops i8mem:$dst), "setp $dst", []>, TB; // [mem8] = parity
1839 def SETNPr : I<0x9B, MRM0r,
1840 (ops R8 :$dst), "setnp $dst", []>, TB; // R8 = not parity
1841 def SETNPm : I<0x9B, MRM0m,
1842 (ops i8mem:$dst), "setnp $dst", []>, TB; // [mem8] = not parity
1843 def SETLr : I<0x9C, MRM0r,
1844 (ops R8 :$dst), "setl $dst", []>, TB; // R8 = < signed
1845 def SETLm : I<0x9C, MRM0m,
1846 (ops i8mem:$dst), "setl $dst", []>, TB; // [mem8] = < signed
1847 def SETGEr : I<0x9D, MRM0r,
1848 (ops R8 :$dst), "setge $dst", []>, TB; // R8 = >= signed
1849 def SETGEm : I<0x9D, MRM0m,
1850 (ops i8mem:$dst), "setge $dst", []>, TB; // [mem8] = >= signed
1851 def SETLEr : I<0x9E, MRM0r,
1852 (ops R8 :$dst), "setle $dst", []>, TB; // R8 = <= signed
1853 def SETLEm : I<0x9E, MRM0m,
1854 (ops i8mem:$dst), "setle $dst", []>, TB; // [mem8] = <= signed
1855 def SETGr : I<0x9F, MRM0r,
1856 (ops R8 :$dst), "setg $dst", []>, TB; // R8 = < signed
1857 def SETGm : I<0x9F, MRM0m,
1858 (ops i8mem:$dst), "setg $dst", []>, TB; // [mem8] = < signed
1860 // Integer comparisons
1861 def CMP8rr : I<0x38, MRMDestReg,
1862 (ops R8 :$src1, R8 :$src2),
1863 "cmp{b} {$src2, $src1|$src1, $src2}",
1864 [(set STATUS, (X86cmp R8:$src1, R8:$src2))]>,
1866 def CMP16rr : I<0x39, MRMDestReg,
1867 (ops R16:$src1, R16:$src2),
1868 "cmp{w} {$src2, $src1|$src1, $src2}",
1869 [(set STATUS, (X86cmp R16:$src1, R16:$src2))]>,
1870 Imp<[],[STATUS]>, OpSize;
1871 def CMP32rr : I<0x39, MRMDestReg,
1872 (ops R32:$src1, R32:$src2),
1873 "cmp{l} {$src2, $src1|$src1, $src2}",
1874 [(set STATUS, (X86cmp R32:$src1, R32:$src2))]>,
1876 def CMP8mr : I<0x38, MRMDestMem,
1877 (ops i8mem :$src1, R8 :$src2),
1878 "cmp{b} {$src2, $src1|$src1, $src2}",
1879 [(set STATUS, (X86cmp (loadi8 addr:$src1), R8:$src2))]>,
1881 def CMP16mr : I<0x39, MRMDestMem,
1882 (ops i16mem:$src1, R16:$src2),
1883 "cmp{w} {$src2, $src1|$src1, $src2}",
1884 [(set STATUS, (X86cmp (loadi16 addr:$src1), R16:$src2))]>,
1885 Imp<[],[STATUS]>, OpSize;
1886 def CMP32mr : I<0x39, MRMDestMem,
1887 (ops i32mem:$src1, R32:$src2),
1888 "cmp{l} {$src2, $src1|$src1, $src2}",
1889 [(set STATUS, (X86cmp (loadi32 addr:$src1), R32:$src2))]>,
1891 def CMP8rm : I<0x3A, MRMSrcMem,
1892 (ops R8 :$src1, i8mem :$src2),
1893 "cmp{b} {$src2, $src1|$src1, $src2}",
1894 [(set STATUS, (X86cmp R8:$src1, (loadi8 addr:$src2)))]>,
1896 def CMP16rm : I<0x3B, MRMSrcMem,
1897 (ops R16:$src1, i16mem:$src2),
1898 "cmp{w} {$src2, $src1|$src1, $src2}",
1899 [(set STATUS, (X86cmp R16:$src1, (loadi16 addr:$src2)))]>,
1900 Imp<[],[STATUS]>, OpSize;
1901 def CMP32rm : I<0x3B, MRMSrcMem,
1902 (ops R32:$src1, i32mem:$src2),
1903 "cmp{l} {$src2, $src1|$src1, $src2}",
1904 [(set STATUS, (X86cmp R32:$src1, (loadi32 addr:$src2)))]>,
1906 def CMP8ri : Ii8<0x80, MRM7r,
1907 (ops R8:$src1, i8imm:$src2),
1908 "cmp{b} {$src2, $src1|$src1, $src2}",
1909 [(set STATUS, (X86cmp R8:$src1, imm:$src2))]>,
1911 def CMP16ri : Ii16<0x81, MRM7r,
1912 (ops R16:$src1, i16imm:$src2),
1913 "cmp{w} {$src2, $src1|$src1, $src2}",
1914 [(set STATUS, (X86cmp R16:$src1, imm:$src2))]>,
1915 Imp<[],[STATUS]>, OpSize;
1916 def CMP32ri : Ii32<0x81, MRM7r,
1917 (ops R32:$src1, i32imm:$src2),
1918 "cmp{l} {$src2, $src1|$src1, $src2}",
1919 [(set STATUS, (X86cmp R32:$src1, imm:$src2))]>,
1921 def CMP8mi : Ii8 <0x80, MRM7m,
1922 (ops i8mem :$src1, i8imm :$src2),
1923 "cmp{b} {$src2, $src1|$src1, $src2}",
1924 [(set STATUS, (X86cmp (loadi8 addr:$src1), imm:$src2))]>,
1926 def CMP16mi : Ii16<0x81, MRM7m,
1927 (ops i16mem:$src1, i16imm:$src2),
1928 "cmp{w} {$src2, $src1|$src1, $src2}",
1929 [(set STATUS, (X86cmp (loadi16 addr:$src1), imm:$src2))]>,
1930 Imp<[],[STATUS]>, OpSize;
1931 def CMP32mi : Ii32<0x81, MRM7m,
1932 (ops i32mem:$src1, i32imm:$src2),
1933 "cmp{l} {$src2, $src1|$src1, $src2}",
1934 [(set STATUS, (X86cmp (loadi32 addr:$src1), imm:$src2))]>,
1937 // Sign/Zero extenders
1938 def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
1939 "movs{bw|x} {$src, $dst|$dst, $src}",
1940 [(set R16:$dst, (sext R8:$src))]>, TB, OpSize;
1941 def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
1942 "movs{bw|x} {$src, $dst|$dst, $src}",
1943 [(set R16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
1944 def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
1945 "movs{bl|x} {$src, $dst|$dst, $src}",
1946 [(set R32:$dst, (sext R8:$src))]>, TB;
1947 def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
1948 "movs{bl|x} {$src, $dst|$dst, $src}",
1949 [(set R32:$dst, (sextloadi32i8 addr:$src))]>, TB;
1950 def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
1951 "movs{wl|x} {$src, $dst|$dst, $src}",
1952 [(set R32:$dst, (sext R16:$src))]>, TB;
1953 def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
1954 "movs{wl|x} {$src, $dst|$dst, $src}",
1955 [(set R32:$dst, (sextloadi32i16 addr:$src))]>, TB;
1957 def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
1958 "movz{bw|x} {$src, $dst|$dst, $src}",
1959 [(set R16:$dst, (zext R8:$src))]>, TB, OpSize;
1960 def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
1961 "movz{bw|x} {$src, $dst|$dst, $src}",
1962 [(set R16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
1963 def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
1964 "movz{bl|x} {$src, $dst|$dst, $src}",
1965 [(set R32:$dst, (zext R8:$src))]>, TB;
1966 def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
1967 "movz{bl|x} {$src, $dst|$dst, $src}",
1968 [(set R32:$dst, (zextloadi32i8 addr:$src))]>, TB;
1969 def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
1970 "movz{wl|x} {$src, $dst|$dst, $src}",
1971 [(set R32:$dst, (zext R16:$src))]>, TB;
1972 def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
1973 "movz{wl|x} {$src, $dst|$dst, $src}",
1974 [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB;
1976 // Handling 1 bit zextload and sextload
1977 def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>;
1978 def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>;
1979 def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
1980 def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
1982 // Handling 1 bit extload
1983 def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
1985 // Modeling anyext as zext
1986 def : Pat<(i16 (anyext R8 :$src)), (MOVZX16rr8 R8 :$src)>;
1987 def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8 R8 :$src)>;
1988 def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>;
1990 //===----------------------------------------------------------------------===//
1991 // XMM Floating point support (requires SSE2)
1992 //===----------------------------------------------------------------------===//
1994 def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
1995 "movss {$src, $dst|$dst, $src}", []>, XS;
1996 def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
1997 "movsd {$src, $dst|$dst, $src}", []>, XD;
1999 def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2000 "movss {$src, $dst|$dst, $src}",
2001 [(set FR32:$dst, (loadf32 addr:$src))]>,
2002 Requires<[HasSSE2]>, XS;
2003 def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src),
2004 "movss {$src, $dst|$dst, $src}",
2005 [(store FR32:$src, addr:$dst)]>, XS;
2006 def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2007 "movsd {$src, $dst|$dst, $src}",
2008 [(set FR64:$dst, (loadf64 addr:$src))]>,
2009 Requires<[HasSSE2]>, XD;
2010 def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src),
2011 "movsd {$src, $dst|$dst, $src}",
2012 [(store FR64:$src, addr:$dst)]>,
2013 Requires<[HasSSE2]>, XD;
2015 def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src),
2016 "cvttsd2si {$src, $dst|$dst, $src}",
2017 [(set R32:$dst, (fp_to_sint FR64:$src))]>,
2018 Requires<[HasSSE2]>, XD;
2019 def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src),
2020 "cvttsd2si {$src, $dst|$dst, $src}",
2021 [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>,
2022 Requires<[HasSSE2]>, XD;
2023 def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src),
2024 "cvttss2si {$src, $dst|$dst, $src}",
2025 [(set R32:$dst, (fp_to_sint FR32:$src))]>,
2026 Requires<[HasSSE2]>, XS;
2027 def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src),
2028 "cvttss2si {$src, $dst|$dst, $src}",
2029 [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>,
2030 Requires<[HasSSE2]>, XS;
2031 def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src),
2032 "cvtsd2ss {$src, $dst|$dst, $src}",
2033 [(set FR32:$dst, (fround FR64:$src))]>,
2034 Requires<[HasSSE2]>, XS;
2035 def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src),
2036 "cvtsd2ss {$src, $dst|$dst, $src}",
2037 [(set FR32:$dst, (fround (loadf64 addr:$src)))]>,
2038 Requires<[HasSSE2]>, XS;
2039 def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src),
2040 "cvtss2sd {$src, $dst|$dst, $src}",
2041 [(set FR64:$dst, (fextend FR32:$src))]>,
2042 Requires<[HasSSE2]>, XD;
2043 def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src),
2044 "cvtss2sd {$src, $dst|$dst, $src}",
2045 [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>,
2046 Requires<[HasSSE2]>, XD;
2047 def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src),
2048 "cvtsi2ss {$src, $dst|$dst, $src}",
2049 [(set FR32:$dst, (sint_to_fp R32:$src))]>,
2050 Requires<[HasSSE2]>, XS;
2051 def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src),
2052 "cvtsi2ss {$src, $dst|$dst, $src}",
2053 [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2054 Requires<[HasSSE2]>, XS;
2055 def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src),
2056 "cvtsi2sd {$src, $dst|$dst, $src}",
2057 [(set FR64:$dst, (sint_to_fp R32:$src))]>,
2058 Requires<[HasSSE2]>, XD;
2059 def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src),
2060 "cvtsi2sd {$src, $dst|$dst, $src}",
2061 [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>,
2062 Requires<[HasSSE2]>, XD;
2064 def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2065 "sqrtss {$src, $dst|$dst, $src}", []>, XS;
2066 def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2067 "sqrtss {$src, $dst|$dst, $src}",
2068 [(set FR32:$dst, (fsqrt FR32:$src))]>, XS;
2069 def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2070 "sqrtsd {$src, $dst|$dst, $src}", []>, XD;
2071 def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2072 "sqrtsd {$src, $dst|$dst, $src}",
2073 [(set FR64:$dst, (fsqrt FR64:$src))]>, XD;
2075 def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$dst, FR64:$src),
2076 "ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
2077 def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
2078 "ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
2079 def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$dst, FR32:$src),
2080 "ucomiss {$src, $dst|$dst, $src}", []>, TB;
2081 def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
2082 "ucomiss {$src, $dst|$dst, $src}", []>, TB;
2084 // Pseudo-instructions that map fld0 to xorps/xorpd for sse.
2085 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
2086 def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst),
2087 "xorps $dst, $dst", []>, TB;
2088 def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst),
2089 "xorpd $dst, $dst", []>, TB, OpSize;
2091 let isTwoAddress = 1 in {
2092 let isCommutable = 1 in {
2093 def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2094 "addss {$src2, $dst|$dst, $src2}",
2095 [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>, XS;
2096 def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2097 "addsd {$src2, $dst|$dst, $src2}",
2098 [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>, XD;
2099 def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2100 "andps {$src2, $dst|$dst, $src2}", []>, TB;
2101 def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2102 "andpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
2103 def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2104 "mulss {$src2, $dst|$dst, $src2}",
2105 [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>, XS;
2106 def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2107 "mulsd {$src2, $dst|$dst, $src2}",
2108 [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>, XD;
2109 def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2110 "orps {$src2, $dst|$dst, $src2}", []>, TB;
2111 def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2112 "orpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
2113 def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2114 "xorps {$src2, $dst|$dst, $src2}", []>, TB;
2115 def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2116 "xorpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
2118 def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2119 "andnps {$src2, $dst|$dst, $src2}", []>, TB;
2120 def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2121 "andnpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
2122 def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2123 "addss {$src2, $dst|$dst, $src2}", []>, XS;
2124 def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2125 "addsd {$src2, $dst|$dst, $src2}", []>, XD;
2126 def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2127 "mulss {$src2, $dst|$dst, $src2}", []>, XS;
2128 def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2129 "mulsd {$src2, $dst|$dst, $src2}", []>, XD;
2131 def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2132 "divss {$src2, $dst|$dst, $src2}", []>, XS;
2133 def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2134 "divss {$src2, $dst|$dst, $src2}",
2135 [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>, XS;
2136 def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2137 "divsd {$src2, $dst|$dst, $src2}", []>, XD;
2138 def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2139 "divsd {$src2, $dst|$dst, $src2}",
2140 [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>, XD;
2142 def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
2143 "subss {$src2, $dst|$dst, $src2}", []>, XS;
2144 def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
2145 "subss {$src2, $dst|$dst, $src2}",
2146 [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>, XS;
2147 def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
2148 "subsd {$src2, $dst|$dst, $src2}", []>, XD;
2149 def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
2150 "subsd {$src2, $dst|$dst, $src2}",
2151 [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>, XD;
2153 def CMPSSrr : I<0xC2, MRMSrcReg,
2154 (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),
2155 "cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
2156 def CMPSSrm : I<0xC2, MRMSrcMem,
2157 (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc),
2158 "cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
2159 def CMPSDrr : I<0xC2, MRMSrcReg,
2160 (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc),
2161 "cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
2162 def CMPSDrm : I<0xC2, MRMSrcMem,
2163 (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc),
2164 "cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
2167 //===----------------------------------------------------------------------===//
2168 // Miscellaneous Instructions
2169 //===----------------------------------------------------------------------===//
2171 def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
2174 //===----------------------------------------------------------------------===//
2175 // Stack-based Floating point support
2176 //===----------------------------------------------------------------------===//
2178 // FIXME: These need to indicate mod/ref sets for FP regs... & FP 'TOP'
2180 // Floating point instruction template
2181 class FPI<bits<8> o, Format F, FPFormat fp, dag ops, string asm,
2183 : X86Inst<o, F, NoImm, ops, asm> {
2184 let FPForm = fp; let FPFormBits = FPForm.Value;
2185 let Pattern = pattern;
2188 // Pseudo instructions for floating point. We use these pseudo instructions
2189 // because they can be expanded by the fp spackifier into one of many different
2190 // forms of instructions for doing these operations. Until the stackifier runs,
2191 // we prefer to be abstract.
2192 def FpMOV : FPI<0, Pseudo, SpecialFP,
2193 (ops RFP:$dst, RFP:$src), "", []>; // f1 = fmov f2
2194 def FpADD : FPI<0, Pseudo, TwoArgFP ,
2195 (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
2196 []>; // f1 = fadd f2, f3
2197 def FpSUB : FPI<0, Pseudo, TwoArgFP ,
2198 (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
2199 []>; // f1 = fsub f2, f3
2200 def FpMUL : FPI<0, Pseudo, TwoArgFP ,
2201 (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
2202 []>; // f1 = fmul f2, f3
2203 def FpDIV : FPI<0, Pseudo, TwoArgFP ,
2204 (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
2205 []>; // f1 = fdiv f2, f3
2207 def FpLD32m : FPI<0xD9, MRM0m, ZeroArgFP,
2208 (ops RFP:$dst, f32mem:$src),
2210 [(set RFP:$dst, (X86fld addr:$src, f32))]>;
2212 def FpLD64m : FPI<0xDD, MRM0m, ZeroArgFP,
2213 (ops RFP:$dst, f64mem:$src),
2215 [(set RFP:$dst, (X86fld addr:$src, f64))]>;
2217 def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "", []>,
2218 Imp<[ST0], []>; // FPR = ST(0)
2220 def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "",
2221 [(X86fpset RFP:$src)]>,
2222 Imp<[], [ST0]>; // ST(0) = FPR
2224 // FADD reg, mem: Before stackification, these are represented by:
2225 // R1 = FADD* R2, [mem]
2226 def FADD32m : FPI<0xD8, MRM0m, OneArgFPRW, // ST(0) = ST(0) + [mem32real]
2227 (ops f32mem:$src, variable_ops),
2228 "fadd{s} $src", []>;
2229 def FADD64m : FPI<0xDC, MRM0m, OneArgFPRW, // ST(0) = ST(0) + [mem64real]
2230 (ops f64mem:$src, variable_ops),
2231 "fadd{l} $src", []>;
2232 //def FIADD16m : FPI<0xDE, MRM0m, OneArgFPRW>; // ST(0) = ST(0) + [mem16int]
2233 //def FIADD32m : FPI<0xDA, MRM0m, OneArgFPRW>; // ST(0) = ST(0) + [mem32int]
2235 // FMUL reg, mem: Before stackification, these are represented by:
2236 // R1 = FMUL* R2, [mem]
2237 def FMUL32m : FPI<0xD8, MRM1m, OneArgFPRW, // ST(0) = ST(0) * [mem32real]
2238 (ops f32mem:$src, variable_ops),
2239 "fmul{s} $src", []>;
2240 def FMUL64m : FPI<0xDC, MRM1m, OneArgFPRW, // ST(0) = ST(0) * [mem64real]
2241 (ops f64mem:$src, variable_ops),
2242 "fmul{l} $src", []>;
2243 // ST(0) = ST(0) * [mem16int]
2244 //def FIMUL16m : FPI16m<"fimul", 0xDE, MRM1m, OneArgFPRW>;
2245 // ST(0) = ST(0) * [mem32int]
2246 //def FIMUL32m : FPI32m<"fimul", 0xDA, MRM1m, OneArgFPRW>;
2248 // FSUB reg, mem: Before stackification, these are represented by:
2249 // R1 = FSUB* R2, [mem]
2250 def FSUB32m : FPI<0xD8, MRM4m, OneArgFPRW, // ST(0) = ST(0) - [mem32real]
2251 (ops f32mem:$src, variable_ops),
2252 "fsub{s} $src", []>;
2253 def FSUB64m : FPI<0xDC, MRM4m, OneArgFPRW, // ST(0) = ST(0) - [mem64real]
2254 (ops f64mem:$src, variable_ops),
2255 "fsub{l} $src", []>;
2256 // ST(0) = ST(0) - [mem16int]
2257 //def FISUB16m : FPI16m<"fisub", 0xDE, MRM4m, OneArgFPRW>;
2258 // ST(0) = ST(0) - [mem32int]
2259 //def FISUB32m : FPI32m<"fisub", 0xDA, MRM4m, OneArgFPRW>;
2261 // FSUBR reg, mem: Before stackification, these are represented by:
2262 // R1 = FSUBR* R2, [mem]
2264 // Note that the order of operands does not reflect the operation being
2266 def FSUBR32m : FPI<0xD8, MRM5m, OneArgFPRW, // ST(0) = [mem32real] - ST(0)
2267 (ops f32mem:$src, variable_ops),
2268 "fsubr{s} $src", []>;
2269 def FSUBR64m : FPI<0xDC, MRM5m, OneArgFPRW, // ST(0) = [mem64real] - ST(0)
2270 (ops f64mem:$src, variable_ops),
2271 "fsubr{l} $src", []>;
2272 // ST(0) = [mem16int] - ST(0)
2273 //def FISUBR16m : FPI16m<"fisubr", 0xDE, MRM5m, OneArgFPRW>;
2274 // ST(0) = [mem32int] - ST(0)
2275 //def FISUBR32m : FPI32m<"fisubr", 0xDA, MRM5m, OneArgFPRW>;
2277 // FDIV reg, mem: Before stackification, these are represented by:
2278 // R1 = FDIV* R2, [mem]
2279 def FDIV32m : FPI<0xD8, MRM6m, OneArgFPRW, // ST(0) = ST(0) / [mem32real]
2280 (ops f32mem:$src, variable_ops),
2281 "fdiv{s} $src", []>;
2282 def FDIV64m : FPI<0xDC, MRM6m, OneArgFPRW, // ST(0) = ST(0) / [mem64real]
2283 (ops f64mem:$src, variable_ops),
2284 "fdiv{l} $src", []>;
2285 // ST(0) = ST(0) / [mem16int]
2286 //def FIDIV16m : FPI16m<"fidiv", 0xDE, MRM6m, OneArgFPRW>;
2287 // ST(0) = ST(0) / [mem32int]
2288 //def FIDIV32m : FPI32m<"fidiv", 0xDA, MRM6m, OneArgFPRW>;
2290 // FDIVR reg, mem: Before stackification, these are represented by:
2291 // R1 = FDIVR* R2, [mem]
2292 // Note that the order of operands does not reflect the operation being
2294 def FDIVR32m : FPI<0xD8, MRM7m, OneArgFPRW, // ST(0) = [mem32real] / ST(0)
2295 (ops f32mem:$src, variable_ops),
2296 "fdivr{s} $src", []>;
2297 def FDIVR64m : FPI<0xDC, MRM7m, OneArgFPRW, // ST(0) = [mem64real] / ST(0)
2298 (ops f64mem:$src, variable_ops),
2299 "fdivr{l} $src", []>;
2300 // ST(0) = [mem16int] / ST(0)
2301 //def FIDIVR16m : FPI16m<"fidivr", 0xDE, MRM7m, OneArgFPRW>;
2302 // ST(0) = [mem32int] / ST(0)
2303 //def FIDIVR32m : FPI32m<"fidivr", 0xDA, MRM7m, OneArgFPRW>;
2306 // Floating point cmovs...
2307 let isTwoAddress = 1, Uses = [ST0], Defs = [ST0] in {
2308 def FCMOVB : FPI<0xC0, AddRegFrm, CondMovFP,
2309 (ops RST:$op, variable_ops),
2310 "fcmovb {$op, %ST(0)|%ST(0), $op}", []>, DA;
2311 def FCMOVBE : FPI<0xD0, AddRegFrm, CondMovFP,
2312 (ops RST:$op, variable_ops),
2313 "fcmovbe {$op, %ST(0)|%ST(0), $op}", []>, DA;
2314 def FCMOVE : FPI<0xC8, AddRegFrm, CondMovFP,
2315 (ops RST:$op, variable_ops),
2316 "fcmove {$op, %ST(0)|%ST(0), $op}", []>, DA;
2317 def FCMOVP : FPI<0xD8, AddRegFrm, CondMovFP,
2318 (ops RST:$op, variable_ops),
2319 "fcmovu {$op, %ST(0)|%ST(0), $op}", []>, DA;
2320 def FCMOVAE : FPI<0xC0, AddRegFrm, CondMovFP,
2321 (ops RST:$op, variable_ops),
2322 "fcmovae {$op, %ST(0)|%ST(0), $op}", []>, DB;
2323 def FCMOVA : FPI<0xD0, AddRegFrm, CondMovFP,
2324 (ops RST:$op, variable_ops),
2325 "fcmova {$op, %ST(0)|%ST(0), $op}", []>, DB;
2326 def FCMOVNE : FPI<0xC8, AddRegFrm, CondMovFP,
2327 (ops RST:$op, variable_ops),
2328 "fcmovne {$op, %ST(0)|%ST(0), $op}", []>, DB;
2329 def FCMOVNP : FPI<0xD8, AddRegFrm, CondMovFP,
2330 (ops RST:$op, variable_ops),
2331 "fcmovnu {$op, %ST(0)|%ST(0), $op}", []>, DB;
2334 // Floating point loads & stores...
2335 // FIXME: these are all marked variable_ops because they have an implicit
2336 // destination. Instructions like FILD* that are generated by the instruction
2337 // selector (not the fp stackifier) need more accurate operand accounting.
2338 def FLDrr : FPI<0xC0, AddRegFrm, NotFP,
2339 (ops RST:$src, variable_ops),
2340 "fld $src", []>, D9;
2341 def FLD32m : FPI<0xD9, MRM0m, ZeroArgFP,
2342 (ops f32mem:$src, variable_ops),
2344 def FLD64m : FPI<0xDD, MRM0m, ZeroArgFP,
2345 (ops f64mem:$src, variable_ops),
2347 def FLD80m : FPI<0xDB, MRM5m, ZeroArgFP,
2348 (ops f80mem:$src, variable_ops),
2350 def FILD16m : FPI<0xDF, MRM0m, ZeroArgFP,
2351 (ops i16mem:$src, variable_ops),
2352 "fild{s} $src", []>;
2353 def FILD32m : FPI<0xDB, MRM0m, ZeroArgFP,
2354 (ops i32mem:$src, variable_ops),
2355 "fild{l} $src", []>;
2356 def FILD64m : FPI<0xDF, MRM5m, ZeroArgFP,
2357 (ops i64mem:$src, variable_ops),
2358 "fild{ll} $src", []>;
2360 def FSTrr : FPI<0xD0, AddRegFrm, NotFP,
2361 (ops RST:$op, variable_ops),
2363 def FSTPrr : FPI<0xD8, AddRegFrm, NotFP,
2364 (ops RST:$op, variable_ops),
2365 "fstp $op", []>, DD;
2366 def FST32m : FPI<0xD9, MRM2m, OneArgFP,
2367 (ops f32mem:$op, variable_ops),
2369 def FST64m : FPI<0xDD, MRM2m, OneArgFP,
2370 (ops f64mem:$op, variable_ops),
2372 def FSTP32m : FPI<0xD9, MRM3m, OneArgFP,
2373 (ops f32mem:$op, variable_ops),
2375 def FSTP64m : FPI<0xDD, MRM3m, OneArgFP,
2376 (ops f64mem:$op, variable_ops),
2378 def FSTP80m : FPI<0xDB, MRM7m, OneArgFP,
2379 (ops f80mem:$op, variable_ops),
2382 def FIST16m : FPI<0xDF, MRM2m , OneArgFP,
2383 (ops i16mem:$op, variable_ops),
2385 def FIST32m : FPI<0xDB, MRM2m , OneArgFP,
2386 (ops i32mem:$op, variable_ops),
2388 def FISTP16m : FPI<0xDF, MRM3m , NotFP ,
2389 (ops i16mem:$op, variable_ops),
2390 "fistp{s} $op", []>;
2391 def FISTP32m : FPI<0xDB, MRM3m , NotFP ,
2392 (ops i32mem:$op, variable_ops),
2393 "fistp{l} $op", []>;
2394 def FISTP64m : FPI<0xDF, MRM7m , OneArgFP,
2395 (ops i64mem:$op, variable_ops),
2396 "fistp{ll} $op", []>;
2398 def FXCH : FPI<0xC8, AddRegFrm, NotFP,
2399 (ops RST:$op), "fxch $op", []>, D9; // fxch ST(i), ST(0)
2401 // Floating point constant loads...
2402 def FLD0 : FPI<0xEE, RawFrm, ZeroArgFP, (ops variable_ops), "fldz", []>, D9;
2403 def FLD1 : FPI<0xE8, RawFrm, ZeroArgFP, (ops variable_ops), "fld1", []>, D9;
2406 // Unary operations...
2407 def FCHS : FPI<0xE0, RawFrm, OneArgFPRW, // f1 = fchs f2
2410 def FABS : FPI<0xE1, RawFrm, OneArgFPRW, // f1 = fabs f2
2413 def FSQRT : FPI<0xFA, RawFrm, OneArgFPRW, // fsqrt ST(0)
2416 def FSIN : FPI<0xFE, RawFrm, OneArgFPRW, // fsin ST(0)
2419 def FCOS : FPI<0xFF, RawFrm, OneArgFPRW, // fcos ST(0)
2422 def FTST : FPI<0xE4, RawFrm, OneArgFP , // ftst ST(0)
2426 // Binary arithmetic operations...
2427 class FPST0rInst<bits<8> o, dag ops, string asm>
2428 : I<o, AddRegFrm, ops, asm, []>, D8 {
2429 list<Register> Uses = [ST0];
2430 list<Register> Defs = [ST0];
2432 class FPrST0Inst<bits<8> o, dag ops, string asm>
2433 : I<o, AddRegFrm, ops, asm, []>, DC {
2434 list<Register> Uses = [ST0];
2436 class FPrST0PInst<bits<8> o, dag ops, string asm>
2437 : I<o, AddRegFrm, ops, asm, []>, DE {
2438 list<Register> Uses = [ST0];
2441 def FADDST0r : FPST0rInst <0xC0, (ops RST:$op),
2443 def FADDrST0 : FPrST0Inst <0xC0, (ops RST:$op),
2444 "fadd {%ST(0), $op|$op, %ST(0)}">;
2445 def FADDPrST0 : FPrST0PInst<0xC0, (ops RST:$op),
2448 // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
2449 // of some of the 'reverse' forms of the fsub and fdiv instructions. As such,
2450 // we have to put some 'r's in and take them out of weird places.
2451 def FSUBRST0r : FPST0rInst <0xE8, (ops RST:$op),
2453 def FSUBrST0 : FPrST0Inst <0xE8, (ops RST:$op),
2454 "fsub{r} {%ST(0), $op|$op, %ST(0)}">;
2455 def FSUBPrST0 : FPrST0PInst<0xE8, (ops RST:$op),
2458 def FSUBST0r : FPST0rInst <0xE0, (ops RST:$op),
2460 def FSUBRrST0 : FPrST0Inst <0xE0, (ops RST:$op),
2461 "fsub{|r} {%ST(0), $op|$op, %ST(0)}">;
2462 def FSUBRPrST0 : FPrST0PInst<0xE0, (ops RST:$op),
2465 def FMULST0r : FPST0rInst <0xC8, (ops RST:$op),
2467 def FMULrST0 : FPrST0Inst <0xC8, (ops RST:$op),
2468 "fmul {%ST(0), $op|$op, %ST(0)}">;
2469 def FMULPrST0 : FPrST0PInst<0xC8, (ops RST:$op),
2472 def FDIVRST0r : FPST0rInst <0xF8, (ops RST:$op),
2474 def FDIVrST0 : FPrST0Inst <0xF8, (ops RST:$op),
2475 "fdiv{r} {%ST(0), $op|$op, %ST(0)}">;
2476 def FDIVPrST0 : FPrST0PInst<0xF8, (ops RST:$op),
2479 def FDIVST0r : FPST0rInst <0xF0, (ops RST:$op), // ST(0) = ST(0) / ST(i)
2481 def FDIVRrST0 : FPrST0Inst <0xF0, (ops RST:$op), // ST(i) = ST(0) / ST(i)
2482 "fdiv{|r} {%ST(0), $op|$op, %ST(0)}">;
2483 def FDIVRPrST0 : FPrST0PInst<0xF0, (ops RST:$op), // ST(i) = ST(0) / ST(i), pop
2486 // Floating point compares
2487 def FUCOMr : FPI<0xE0, AddRegFrm, CompareFP, // FPSW = cmp ST(0) with ST(i)
2488 (ops RST:$reg, variable_ops),
2489 "fucom $reg", []>, DD, Imp<[ST0],[]>;
2490 def FUCOMPr : I<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop
2491 (ops RST:$reg, variable_ops),
2492 "fucomp $reg", []>, DD, Imp<[ST0],[]>;
2493 def FUCOMPPr : I<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop
2495 "fucompp", []>, DA, Imp<[ST0],[]>;
2497 def FUCOMIr : FPI<0xE8, AddRegFrm, CompareFP, // CC = cmp ST(0) with ST(i)
2498 (ops RST:$reg, variable_ops),
2499 "fucomi {$reg, %ST(0)|%ST(0), $reg}", []>, DB, Imp<[ST0],[]>;
2500 def FUCOMIPr : I<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop
2501 (ops RST:$reg, variable_ops),
2502 "fucomip {$reg, %ST(0)|%ST(0), $reg}", []>, DF, Imp<[ST0],[]>;
2505 // Floating point flag ops
2506 def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags
2507 (ops), "fnstsw", []>, DF, Imp<[],[AX]>;
2509 def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
2510 (ops i16mem:$dst), "fnstcw $dst", []>;
2511 def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
2512 (ops i16mem:$dst), "fldcw $dst", []>;