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