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