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