blob: b24f6442074eddbc43aa53dafbfe842c075805cb [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===- X86InstrInfo.td - Describe the X86 Instruction Set -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
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.
13//
14//===----------------------------------------------------------------------===//
15
16//===----------------------------------------------------------------------===//
17// X86 specific DAG Nodes.
18//
19
20def SDTIntShiftDOp: SDTypeProfile<1, 3,
21 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22 SDTCisInt<0>, SDTCisInt<3>]>;
23
24def SDTX86CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
25
26def SDTX86Cmov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
28 SDTCisVT<3, i8>]>;
29
30def SDTX86BrCond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>;
32
33def SDTX86SetCC : SDTypeProfile<1, 1,
34 [SDTCisVT<0, i8>, SDTCisVT<1, i8>]>;
35
36def SDTX86Ret : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
37
38def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
39def SDT_X86CallSeqEnd : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
40 SDTCisVT<1, i32> ]>;
41
42def SDT_X86Call : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
43
44def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
45
46def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
47
48def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
49
50def SDT_X86TLSADDR : SDTypeProfile<1, 1, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
51
52def SDT_X86TLSTP : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
53
54def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
55
56def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
57def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
58
59def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest,
60 [SDNPHasChain, SDNPOutFlag]>;
61
62def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov,
63 [SDNPInFlag, SDNPOutFlag]>;
64def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
65 [SDNPHasChain, SDNPInFlag]>;
66def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC,
67 [SDNPInFlag, SDNPOutFlag]>;
68
69def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
70 [SDNPHasChain, SDNPOptInFlag]>;
71
72def X86callseq_start :
73 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
74 [SDNPHasChain, SDNPOutFlag]>;
75def X86callseq_end :
76 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
77 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
78
79def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
80 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
81
82def X86tailcall: SDNode<"X86ISD::TAILCALL", SDT_X86Call,
83 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
84
85def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
86 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
87def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
88 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
89
90def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
91 [SDNPHasChain, SDNPOutFlag]>;
92
93def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
94def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
95
96def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
97 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
98def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
99
100def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
101 [SDNPHasChain]>;
102
103
104//===----------------------------------------------------------------------===//
105// X86 Operand Definitions.
106//
107
108// *mem - Operand definitions for the funky X86 addressing mode operands.
109//
110class X86MemOperand<string printMethod> : Operand<iPTR> {
111 let PrintMethod = printMethod;
112 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc, i32imm);
113}
114
115def i8mem : X86MemOperand<"printi8mem">;
116def i16mem : X86MemOperand<"printi16mem">;
117def i32mem : X86MemOperand<"printi32mem">;
118def i64mem : X86MemOperand<"printi64mem">;
119def i128mem : X86MemOperand<"printi128mem">;
120def f32mem : X86MemOperand<"printf32mem">;
121def f64mem : X86MemOperand<"printf64mem">;
122def f128mem : X86MemOperand<"printf128mem">;
123
124def lea32mem : Operand<i32> {
125 let PrintMethod = "printi32mem";
126 let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
127}
128
129def SSECC : Operand<i8> {
130 let PrintMethod = "printSSECC";
131}
132
133def piclabel: Operand<i32> {
134 let PrintMethod = "printPICLabel";
135}
136
137// A couple of more descriptive operand definitions.
138// 16-bits but only 8 bits are significant.
139def i16i8imm : Operand<i16>;
140// 32-bits but only 8 bits are significant.
141def i32i8imm : Operand<i32>;
142
143// Branch targets have OtherVT type.
144def brtarget : Operand<OtherVT>;
145
146//===----------------------------------------------------------------------===//
147// X86 Complex Pattern Definitions.
148//
149
150// Define X86 specific addressing mode.
151def addr : ComplexPattern<iPTR, 4, "SelectAddr", [], []>;
152def lea32addr : ComplexPattern<i32, 4, "SelectLEAAddr",
153 [add, mul, shl, or, frameindex], []>;
154
155//===----------------------------------------------------------------------===//
156// X86 Instruction Format Definitions.
157//
158
159// Format specifies the encoding used by the instruction. This is part of the
160// ad-hoc solution used to emit machine instruction encodings by our machine
161// code emitter.
162class Format<bits<6> val> {
163 bits<6> Value = val;
164}
165
166def Pseudo : Format<0>; def RawFrm : Format<1>;
167def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
168def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
169def MRMSrcMem : Format<6>;
170def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
171def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
172def MRM6r : Format<22>; def MRM7r : Format<23>;
173def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
174def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
175def MRM6m : Format<30>; def MRM7m : Format<31>;
176def MRMInitReg : Format<32>;
177
178//===----------------------------------------------------------------------===//
179// X86 Instruction Predicate Definitions.
180def HasMMX : Predicate<"Subtarget->hasMMX()">;
181def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
182def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
183def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
184def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
185def FPStack : Predicate<"!Subtarget->hasSSE2()">;
186def In32BitMode : Predicate<"!Subtarget->is64Bit()">;
187def In64BitMode : Predicate<"Subtarget->is64Bit()">;
188def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
189def NotSmallCode : Predicate<"TM.getCodeModel() != CodeModel::Small">;
190def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
191
192//===----------------------------------------------------------------------===//
193// X86 specific pattern fragments.
194//
195
196// ImmType - This specifies the immediate type used by an instruction. This is
197// part of the ad-hoc solution used to emit machine instruction encodings by our
198// machine code emitter.
199class ImmType<bits<3> val> {
200 bits<3> Value = val;
201}
202def NoImm : ImmType<0>;
203def Imm8 : ImmType<1>;
204def Imm16 : ImmType<2>;
205def Imm32 : ImmType<3>;
206def Imm64 : ImmType<4>;
207
208// FPFormat - This specifies what form this FP instruction has. This is used by
209// the Floating-Point stackifier pass.
210class FPFormat<bits<3> val> {
211 bits<3> Value = val;
212}
213def NotFP : FPFormat<0>;
214def ZeroArgFP : FPFormat<1>;
215def OneArgFP : FPFormat<2>;
216def OneArgFPRW : FPFormat<3>;
217def TwoArgFP : FPFormat<4>;
218def CompareFP : FPFormat<5>;
219def CondMovFP : FPFormat<6>;
220def SpecialFP : FPFormat<7>;
221
222
223class X86Inst<bits<8> opcod, Format f, ImmType i, dag ops, string AsmStr>
224 : Instruction {
225 let Namespace = "X86";
226
227 bits<8> Opcode = opcod;
228 Format Form = f;
229 bits<6> FormBits = Form.Value;
230 ImmType ImmT = i;
231 bits<3> ImmTypeBits = ImmT.Value;
232
233 dag OperandList = ops;
234 string AsmString = AsmStr;
235
236 //
237 // Attributes specific to X86 instructions...
238 //
239 bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix?
240 bit hasAdSizePrefix = 0; // Does this inst have a 0x67 prefix?
241
242 bits<4> Prefix = 0; // Which prefix byte does this inst have?
243 bit hasREX_WPrefix = 0; // Does this inst requires the REX.W prefix?
244 FPFormat FPForm; // What flavor of FP instruction is this?
245 bits<3> FPFormBits = 0;
246}
247
248
249// Prefix byte classes which are used to indicate to the ad-hoc machine code
250// emitter that various prefix bytes are required.
251class OpSize { bit hasOpSizePrefix = 1; }
252class AdSize { bit hasAdSizePrefix = 1; }
253class REX_W { bit hasREX_WPrefix = 1; }
254class TB { bits<4> Prefix = 1; }
255class REP { bits<4> Prefix = 2; }
256class D8 { bits<4> Prefix = 3; }
257class D9 { bits<4> Prefix = 4; }
258class DA { bits<4> Prefix = 5; }
259class DB { bits<4> Prefix = 6; }
260class DC { bits<4> Prefix = 7; }
261class DD { bits<4> Prefix = 8; }
262class DE { bits<4> Prefix = 9; }
263class DF { bits<4> Prefix = 10; }
264class XD { bits<4> Prefix = 11; }
265class XS { bits<4> Prefix = 12; }
266class T8 { bits<4> Prefix = 13; }
267class TA { bits<4> Prefix = 14; }
268
269
270//===----------------------------------------------------------------------===//
271// Pattern fragments...
272//
273
274// X86 specific condition code. These correspond to CondCode in
275// X86InstrInfo.h. They must be kept in synch.
276def X86_COND_A : PatLeaf<(i8 0)>;
277def X86_COND_AE : PatLeaf<(i8 1)>;
278def X86_COND_B : PatLeaf<(i8 2)>;
279def X86_COND_BE : PatLeaf<(i8 3)>;
280def X86_COND_E : PatLeaf<(i8 4)>;
281def X86_COND_G : PatLeaf<(i8 5)>;
282def X86_COND_GE : PatLeaf<(i8 6)>;
283def X86_COND_L : PatLeaf<(i8 7)>;
284def X86_COND_LE : PatLeaf<(i8 8)>;
285def X86_COND_NE : PatLeaf<(i8 9)>;
286def X86_COND_NO : PatLeaf<(i8 10)>;
287def X86_COND_NP : PatLeaf<(i8 11)>;
288def X86_COND_NS : PatLeaf<(i8 12)>;
289def X86_COND_O : PatLeaf<(i8 13)>;
290def X86_COND_P : PatLeaf<(i8 14)>;
291def X86_COND_S : PatLeaf<(i8 15)>;
292
293def i16immSExt8 : PatLeaf<(i16 imm), [{
294 // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit
295 // sign extended field.
296 return (int16_t)N->getValue() == (int8_t)N->getValue();
297}]>;
298
299def i32immSExt8 : PatLeaf<(i32 imm), [{
300 // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
301 // sign extended field.
302 return (int32_t)N->getValue() == (int8_t)N->getValue();
303}]>;
304
305// Helper fragments for loads.
306def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
307def loadi16 : PatFrag<(ops node:$ptr), (i16 (load node:$ptr))>;
308def loadi32 : PatFrag<(ops node:$ptr), (i32 (load node:$ptr))>;
309def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
310
311def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
312def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
313
314def sextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (sextloadi1 node:$ptr))>;
315def sextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (sextloadi1 node:$ptr))>;
316def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
317def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
318def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
319
320def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
321def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
322def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
323def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
324def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
325def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
326
327def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
328def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
329def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
330def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
331def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
332def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
333
334//===----------------------------------------------------------------------===//
335// Instruction templates...
336//
337
338class I<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
339 : X86Inst<o, f, NoImm, ops, asm> {
340 let Pattern = pattern;
341 let CodeSize = 3;
342}
343class Ii8 <bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
344 : X86Inst<o, f, Imm8 , ops, asm> {
345 let Pattern = pattern;
346 let CodeSize = 3;
347}
348class Ii16<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
349 : X86Inst<o, f, Imm16, ops, asm> {
350 let Pattern = pattern;
351 let CodeSize = 3;
352}
353class Ii32<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
354 : X86Inst<o, f, Imm32, ops, asm> {
355 let Pattern = pattern;
356 let CodeSize = 3;
357}
358
359//===----------------------------------------------------------------------===//
360// Instruction list...
361//
362
363// ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into
364// a stack adjustment and the codegen must know that they may modify the stack
365// pointer before prolog-epilog rewriting occurs.
366def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
367 [(X86callseq_start imm:$amt)]>, Imp<[ESP],[ESP]>;
368def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
369 "#ADJCALLSTACKUP",
370 [(X86callseq_end imm:$amt1, imm:$amt2)]>,
371 Imp<[ESP],[ESP]>;
372def IMPLICIT_USE : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
373def IMPLICIT_DEF : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
374def IMPLICIT_DEF_GR8 : I<0, Pseudo, (ops GR8:$dst),
375 "#IMPLICIT_DEF $dst",
376 [(set GR8:$dst, (undef))]>;
377def IMPLICIT_DEF_GR16 : I<0, Pseudo, (ops GR16:$dst),
378 "#IMPLICIT_DEF $dst",
379 [(set GR16:$dst, (undef))]>;
380def IMPLICIT_DEF_GR32 : I<0, Pseudo, (ops GR32:$dst),
381 "#IMPLICIT_DEF $dst",
382 [(set GR32:$dst, (undef))]>;
383
384// Nop
385def NOOP : I<0x90, RawFrm, (ops), "nop", []>;
386
387// Truncate
388def TRUNC_32_to8 : I<0x88, MRMDestReg, (ops GR8:$dst, GR32_:$src),
389 "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}", []>;
390def TRUNC_16_to8 : I<0x88, MRMDestReg, (ops GR8:$dst, GR16_:$src),
391 "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}}", []>;
392def TRUNC_32to16 : I<0x89, MRMDestReg, (ops GR16:$dst, GR32:$src),
393 "mov{w} {${src:subreg16}, $dst|$dst, ${src:subreg16}}",
394 [(set GR16:$dst, (trunc GR32:$src))]>;
395
396//===----------------------------------------------------------------------===//
397// Control Flow Instructions...
398//
399
400// Return instructions.
401let isTerminator = 1, isReturn = 1, isBarrier = 1,
402 hasCtrlDep = 1, noResults = 1 in {
403 def RET : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
404 def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
405 [(X86retflag imm:$amt)]>;
406}
407
408// All branches are RawFrm, Void, Branch, and Terminators
409let isBranch = 1, isTerminator = 1, noResults = 1 in
410 class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
411 I<opcode, RawFrm, ops, asm, pattern>;
412
413// Indirect branches
414let isBranch = 1, isBarrier = 1 in
415 def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
416
417let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in {
418 def JMP32r : I<0xFF, MRM4r, (ops GR32:$dst), "jmp{l} {*}$dst",
419 [(brind GR32:$dst)]>;
420 def JMP32m : I<0xFF, MRM4m, (ops i32mem:$dst), "jmp{l} {*}$dst",
421 [(brind (loadi32 addr:$dst))]>;
422}
423
424// Conditional branches
425def JE : IBr<0x84, (ops brtarget:$dst), "je $dst",
426 [(X86brcond bb:$dst, X86_COND_E)]>, TB;
427def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
428 [(X86brcond bb:$dst, X86_COND_NE)]>, TB;
429def JL : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
430 [(X86brcond bb:$dst, X86_COND_L)]>, TB;
431def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
432 [(X86brcond bb:$dst, X86_COND_LE)]>, TB;
433def JG : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
434 [(X86brcond bb:$dst, X86_COND_G)]>, TB;
435def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
436 [(X86brcond bb:$dst, X86_COND_GE)]>, TB;
437
438def JB : IBr<0x82, (ops brtarget:$dst), "jb $dst",
439 [(X86brcond bb:$dst, X86_COND_B)]>, TB;
440def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
441 [(X86brcond bb:$dst, X86_COND_BE)]>, TB;
442def JA : IBr<0x87, (ops brtarget:$dst), "ja $dst",
443 [(X86brcond bb:$dst, X86_COND_A)]>, TB;
444def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
445 [(X86brcond bb:$dst, X86_COND_AE)]>, TB;
446
447def JS : IBr<0x88, (ops brtarget:$dst), "js $dst",
448 [(X86brcond bb:$dst, X86_COND_S)]>, TB;
449def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst",
450 [(X86brcond bb:$dst, X86_COND_NS)]>, TB;
451def JP : IBr<0x8A, (ops brtarget:$dst), "jp $dst",
452 [(X86brcond bb:$dst, X86_COND_P)]>, TB;
453def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst",
454 [(X86brcond bb:$dst, X86_COND_NP)]>, TB;
455def JO : IBr<0x80, (ops brtarget:$dst), "jo $dst",
456 [(X86brcond bb:$dst, X86_COND_O)]>, TB;
457def JNO : IBr<0x81, (ops brtarget:$dst), "jno $dst",
458 [(X86brcond bb:$dst, X86_COND_NO)]>, TB;
459
460//===----------------------------------------------------------------------===//
461// Call Instructions...
462//
463let isCall = 1, noResults = 1 in
464 // All calls clobber the non-callee saved registers...
465 let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
466 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
467 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
468 def CALLpcrel32 : I<0xE8, RawFrm, (ops i32imm:$dst, variable_ops),
469 "call ${dst:call}", []>;
470 def CALL32r : I<0xFF, MRM2r, (ops GR32:$dst, variable_ops),
471 "call {*}$dst", [(X86call GR32:$dst)]>;
472 def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst, variable_ops),
473 "call {*}$dst", []>;
474 }
475
476// Tail call stuff.
477let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
478 def TAILJMPd : IBr<0xE9, (ops i32imm:$dst), "jmp ${dst:call} # TAIL CALL",
479 []>;
480let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
481 def TAILJMPr : I<0xFF, MRM4r, (ops GR32:$dst), "jmp {*}$dst # TAIL CALL",
482 []>;
483let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
484 def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
485 "jmp {*}$dst # TAIL CALL", []>;
486
487//===----------------------------------------------------------------------===//
488// Miscellaneous Instructions...
489//
490def LEAVE : I<0xC9, RawFrm,
491 (ops), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
492def POP32r : I<0x58, AddRegFrm,
493 (ops GR32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
494
495def PUSH32r : I<0x50, AddRegFrm,
496 (ops GR32:$reg), "push{l} $reg", []>, Imp<[ESP],[ESP]>;
497
498def MovePCtoStack : I<0, Pseudo, (ops piclabel:$label),
499 "call $label", []>;
500
501let isTwoAddress = 1 in // GR32 = bswap GR32
502 def BSWAP32r : I<0xC8, AddRegFrm,
503 (ops GR32:$dst, GR32:$src),
504 "bswap{l} $dst",
505 [(set GR32:$dst, (bswap GR32:$src))]>, TB;
506
507def XCHG8rr : I<0x86, MRMDestReg, // xchg GR8, GR8
508 (ops GR8:$src1, GR8:$src2),
509 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
510def XCHG16rr : I<0x87, MRMDestReg, // xchg GR16, GR16
511 (ops GR16:$src1, GR16:$src2),
512 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
513def XCHG32rr : I<0x87, MRMDestReg, // xchg GR32, GR32
514 (ops GR32:$src1, GR32:$src2),
515 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
516
517def XCHG8mr : I<0x86, MRMDestMem,
518 (ops i8mem:$src1, GR8:$src2),
519 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
520def XCHG16mr : I<0x87, MRMDestMem,
521 (ops i16mem:$src1, GR16:$src2),
522 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
523def XCHG32mr : I<0x87, MRMDestMem,
524 (ops i32mem:$src1, GR32:$src2),
525 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
526def XCHG8rm : I<0x86, MRMSrcMem,
527 (ops GR8:$src1, i8mem:$src2),
528 "xchg{b} {$src2|$src1}, {$src1|$src2}", []>;
529def XCHG16rm : I<0x87, MRMSrcMem,
530 (ops GR16:$src1, i16mem:$src2),
531 "xchg{w} {$src2|$src1}, {$src1|$src2}", []>, OpSize;
532def XCHG32rm : I<0x87, MRMSrcMem,
533 (ops GR32:$src1, i32mem:$src2),
534 "xchg{l} {$src2|$src1}, {$src1|$src2}", []>;
535
536def LEA16r : I<0x8D, MRMSrcMem,
537 (ops GR16:$dst, i32mem:$src),
538 "lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
539def LEA32r : I<0x8D, MRMSrcMem,
540 (ops GR32:$dst, lea32mem:$src),
541 "lea{l} {$src|$dst}, {$dst|$src}",
542 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In32BitMode]>;
543
544def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}",
545 [(X86rep_movs i8)]>,
546 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
547def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}",
548 [(X86rep_movs i16)]>,
549 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
550def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsl|rep movsd}",
551 [(X86rep_movs i32)]>,
552 Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
553
554def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}",
555 [(X86rep_stos i8)]>,
556 Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
557def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}",
558 [(X86rep_stos i16)]>,
559 Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
560def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
561 [(X86rep_stos i32)]>,
562 Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
563
564def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
565 TB, Imp<[],[RAX,RDX]>;
566
567//===----------------------------------------------------------------------===//
568// Input/Output Instructions...
569//
570def IN8rr : I<0xEC, RawFrm, (ops),
571 "in{b} {%dx, %al|%AL, %DX}",
572 []>, Imp<[DX], [AL]>;
573def IN16rr : I<0xED, RawFrm, (ops),
574 "in{w} {%dx, %ax|%AX, %DX}",
575 []>, Imp<[DX], [AX]>, OpSize;
576def IN32rr : I<0xED, RawFrm, (ops),
577 "in{l} {%dx, %eax|%EAX, %DX}",
578 []>, Imp<[DX],[EAX]>;
579
580def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port),
581 "in{b} {$port, %al|%AL, $port}",
582 []>,
583 Imp<[], [AL]>;
584def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
585 "in{w} {$port, %ax|%AX, $port}",
586 []>,
587 Imp<[], [AX]>, OpSize;
588def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port),
589 "in{l} {$port, %eax|%EAX, $port}",
590 []>,
591 Imp<[],[EAX]>;
592
593def OUT8rr : I<0xEE, RawFrm, (ops),
594 "out{b} {%al, %dx|%DX, %AL}",
595 []>, Imp<[DX, AL], []>;
596def OUT16rr : I<0xEF, RawFrm, (ops),
597 "out{w} {%ax, %dx|%DX, %AX}",
598 []>, Imp<[DX, AX], []>, OpSize;
599def OUT32rr : I<0xEF, RawFrm, (ops),
600 "out{l} {%eax, %dx|%DX, %EAX}",
601 []>, Imp<[DX, EAX], []>;
602
603def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port),
604 "out{b} {%al, $port|$port, %AL}",
605 []>,
606 Imp<[AL], []>;
607def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
608 "out{w} {%ax, $port|$port, %AX}",
609 []>,
610 Imp<[AX], []>, OpSize;
611def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port),
612 "out{l} {%eax, $port|$port, %EAX}",
613 []>,
614 Imp<[EAX], []>;
615
616//===----------------------------------------------------------------------===//
617// Move Instructions...
618//
619def MOV8rr : I<0x88, MRMDestReg, (ops GR8 :$dst, GR8 :$src),
620 "mov{b} {$src, $dst|$dst, $src}", []>;
621def MOV16rr : I<0x89, MRMDestReg, (ops GR16:$dst, GR16:$src),
622 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
623def MOV32rr : I<0x89, MRMDestReg, (ops GR32:$dst, GR32:$src),
624 "mov{l} {$src, $dst|$dst, $src}", []>;
625let isReMaterializable = 1 in {
626def MOV8ri : Ii8 <0xB0, AddRegFrm, (ops GR8 :$dst, i8imm :$src),
627 "mov{b} {$src, $dst|$dst, $src}",
628 [(set GR8:$dst, imm:$src)]>;
629def MOV16ri : Ii16<0xB8, AddRegFrm, (ops GR16:$dst, i16imm:$src),
630 "mov{w} {$src, $dst|$dst, $src}",
631 [(set GR16:$dst, imm:$src)]>, OpSize;
632def MOV32ri : Ii32<0xB8, AddRegFrm, (ops GR32:$dst, i32imm:$src),
633 "mov{l} {$src, $dst|$dst, $src}",
634 [(set GR32:$dst, imm:$src)]>;
635}
636def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
637 "mov{b} {$src, $dst|$dst, $src}",
638 [(store (i8 imm:$src), addr:$dst)]>;
639def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src),
640 "mov{w} {$src, $dst|$dst, $src}",
641 [(store (i16 imm:$src), addr:$dst)]>, OpSize;
642def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src),
643 "mov{l} {$src, $dst|$dst, $src}",
644 [(store (i32 imm:$src), addr:$dst)]>;
645
646def MOV8rm : I<0x8A, MRMSrcMem, (ops GR8 :$dst, i8mem :$src),
647 "mov{b} {$src, $dst|$dst, $src}",
648 [(set GR8:$dst, (load addr:$src))]>;
649def MOV16rm : I<0x8B, MRMSrcMem, (ops GR16:$dst, i16mem:$src),
650 "mov{w} {$src, $dst|$dst, $src}",
651 [(set GR16:$dst, (load addr:$src))]>, OpSize;
652def MOV32rm : I<0x8B, MRMSrcMem, (ops GR32:$dst, i32mem:$src),
653 "mov{l} {$src, $dst|$dst, $src}",
654 [(set GR32:$dst, (load addr:$src))]>;
655
656def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, GR8 :$src),
657 "mov{b} {$src, $dst|$dst, $src}",
658 [(store GR8:$src, addr:$dst)]>;
659def MOV16mr : I<0x89, MRMDestMem, (ops i16mem:$dst, GR16:$src),
660 "mov{w} {$src, $dst|$dst, $src}",
661 [(store GR16:$src, addr:$dst)]>, OpSize;
662def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, GR32:$src),
663 "mov{l} {$src, $dst|$dst, $src}",
664 [(store GR32:$src, addr:$dst)]>;
665
666//===----------------------------------------------------------------------===//
667// Fixed-Register Multiplication and Division Instructions...
668//
669
670// Extra precision multiplication
671def MUL8r : I<0xF6, MRM4r, (ops GR8:$src), "mul{b} $src",
672 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
673 // This probably ought to be moved to a def : Pat<> if the
674 // syntax can be accepted.
675 [(set AL, (mul AL, GR8:$src))]>,
676 Imp<[AL],[AX]>; // AL,AH = AL*GR8
677def MUL16r : I<0xF7, MRM4r, (ops GR16:$src), "mul{w} $src", []>,
678 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*GR16
679def MUL32r : I<0xF7, MRM4r, (ops GR32:$src), "mul{l} $src", []>,
680 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*GR32
681def MUL8m : I<0xF6, MRM4m, (ops i8mem :$src),
682 "mul{b} $src",
683 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
684 // This probably ought to be moved to a def : Pat<> if the
685 // syntax can be accepted.
686 [(set AL, (mul AL, (loadi8 addr:$src)))]>,
687 Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
688def MUL16m : I<0xF7, MRM4m, (ops i16mem:$src),
689 "mul{w} $src", []>, Imp<[AX],[AX,DX]>,
690 OpSize; // AX,DX = AX*[mem16]
691def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src),
692 "mul{l} $src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
693
694def IMUL8r : I<0xF6, MRM5r, (ops GR8:$src), "imul{b} $src", []>,
695 Imp<[AL],[AX]>; // AL,AH = AL*GR8
696def IMUL16r : I<0xF7, MRM5r, (ops GR16:$src), "imul{w} $src", []>,
697 Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*GR16
698def IMUL32r : I<0xF7, MRM5r, (ops GR32:$src), "imul{l} $src", []>,
699 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*GR32
700def IMUL8m : I<0xF6, MRM5m, (ops i8mem :$src),
701 "imul{b} $src", []>, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
702def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src),
703 "imul{w} $src", []>, Imp<[AX],[AX,DX]>,
704 OpSize; // AX,DX = AX*[mem16]
705def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src),
706 "imul{l} $src", []>,
707 Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
708
709// unsigned division/remainder
710def DIV8r : I<0xF6, MRM6r, (ops GR8:$src), // AX/r8 = AL,AH
711 "div{b} $src", []>, Imp<[AX],[AX]>;
712def DIV16r : I<0xF7, MRM6r, (ops GR16:$src), // DX:AX/r16 = AX,DX
713 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
714def DIV32r : I<0xF7, MRM6r, (ops GR32:$src), // EDX:EAX/r32 = EAX,EDX
715 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
716def DIV8m : I<0xF6, MRM6m, (ops i8mem:$src), // AX/[mem8] = AL,AH
717 "div{b} $src", []>, Imp<[AX],[AX]>;
718def DIV16m : I<0xF7, MRM6m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
719 "div{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
720def DIV32m : I<0xF7, MRM6m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
721 "div{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
722
723// Signed division/remainder.
724def IDIV8r : I<0xF6, MRM7r, (ops GR8:$src), // AX/r8 = AL,AH
725 "idiv{b} $src", []>, Imp<[AX],[AX]>;
726def IDIV16r: I<0xF7, MRM7r, (ops GR16:$src), // DX:AX/r16 = AX,DX
727 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
728def IDIV32r: I<0xF7, MRM7r, (ops GR32:$src), // EDX:EAX/r32 = EAX,EDX
729 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
730def IDIV8m : I<0xF6, MRM7m, (ops i8mem:$src), // AX/[mem8] = AL,AH
731 "idiv{b} $src", []>, Imp<[AX],[AX]>;
732def IDIV16m: I<0xF7, MRM7m, (ops i16mem:$src), // DX:AX/[mem16] = AX,DX
733 "idiv{w} $src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
734def IDIV32m: I<0xF7, MRM7m, (ops i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
735 "idiv{l} $src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
736
737
738//===----------------------------------------------------------------------===//
739// Two address Instructions...
740//
741let isTwoAddress = 1 in {
742
743// Conditional moves
744def CMOVB16rr : I<0x42, MRMSrcReg, // if <u, GR16 = GR16
745 (ops GR16:$dst, GR16:$src1, GR16:$src2),
746 "cmovb {$src2, $dst|$dst, $src2}",
747 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
748 X86_COND_B))]>,
749 TB, OpSize;
750def CMOVB16rm : I<0x42, MRMSrcMem, // if <u, GR16 = [mem16]
751 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
752 "cmovb {$src2, $dst|$dst, $src2}",
753 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
754 X86_COND_B))]>,
755 TB, OpSize;
756def CMOVB32rr : I<0x42, MRMSrcReg, // if <u, GR32 = GR32
757 (ops GR32:$dst, GR32:$src1, GR32:$src2),
758 "cmovb {$src2, $dst|$dst, $src2}",
759 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
760 X86_COND_B))]>,
761 TB;
762def CMOVB32rm : I<0x42, MRMSrcMem, // if <u, GR32 = [mem32]
763 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
764 "cmovb {$src2, $dst|$dst, $src2}",
765 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
766 X86_COND_B))]>,
767 TB;
768
769def CMOVAE16rr: I<0x43, MRMSrcReg, // if >=u, GR16 = GR16
770 (ops GR16:$dst, GR16:$src1, GR16:$src2),
771 "cmovae {$src2, $dst|$dst, $src2}",
772 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
773 X86_COND_AE))]>,
774 TB, OpSize;
775def CMOVAE16rm: I<0x43, MRMSrcMem, // if >=u, GR16 = [mem16]
776 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
777 "cmovae {$src2, $dst|$dst, $src2}",
778 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
779 X86_COND_AE))]>,
780 TB, OpSize;
781def CMOVAE32rr: I<0x43, MRMSrcReg, // if >=u, GR32 = GR32
782 (ops GR32:$dst, GR32:$src1, GR32:$src2),
783 "cmovae {$src2, $dst|$dst, $src2}",
784 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
785 X86_COND_AE))]>,
786 TB;
787def CMOVAE32rm: I<0x43, MRMSrcMem, // if >=u, GR32 = [mem32]
788 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
789 "cmovae {$src2, $dst|$dst, $src2}",
790 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
791 X86_COND_AE))]>,
792 TB;
793
794def CMOVE16rr : I<0x44, MRMSrcReg, // if ==, GR16 = GR16
795 (ops GR16:$dst, GR16:$src1, GR16:$src2),
796 "cmove {$src2, $dst|$dst, $src2}",
797 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
798 X86_COND_E))]>,
799 TB, OpSize;
800def CMOVE16rm : I<0x44, MRMSrcMem, // if ==, GR16 = [mem16]
801 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
802 "cmove {$src2, $dst|$dst, $src2}",
803 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
804 X86_COND_E))]>,
805 TB, OpSize;
806def CMOVE32rr : I<0x44, MRMSrcReg, // if ==, GR32 = GR32
807 (ops GR32:$dst, GR32:$src1, GR32:$src2),
808 "cmove {$src2, $dst|$dst, $src2}",
809 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
810 X86_COND_E))]>,
811 TB;
812def CMOVE32rm : I<0x44, MRMSrcMem, // if ==, GR32 = [mem32]
813 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
814 "cmove {$src2, $dst|$dst, $src2}",
815 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
816 X86_COND_E))]>,
817 TB;
818
819def CMOVNE16rr: I<0x45, MRMSrcReg, // if !=, GR16 = GR16
820 (ops GR16:$dst, GR16:$src1, GR16:$src2),
821 "cmovne {$src2, $dst|$dst, $src2}",
822 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
823 X86_COND_NE))]>,
824 TB, OpSize;
825def CMOVNE16rm: I<0x45, MRMSrcMem, // if !=, GR16 = [mem16]
826 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
827 "cmovne {$src2, $dst|$dst, $src2}",
828 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
829 X86_COND_NE))]>,
830 TB, OpSize;
831def CMOVNE32rr: I<0x45, MRMSrcReg, // if !=, GR32 = GR32
832 (ops GR32:$dst, GR32:$src1, GR32:$src2),
833 "cmovne {$src2, $dst|$dst, $src2}",
834 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
835 X86_COND_NE))]>,
836 TB;
837def CMOVNE32rm: I<0x45, MRMSrcMem, // if !=, GR32 = [mem32]
838 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
839 "cmovne {$src2, $dst|$dst, $src2}",
840 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
841 X86_COND_NE))]>,
842 TB;
843
844def CMOVBE16rr: I<0x46, MRMSrcReg, // if <=u, GR16 = GR16
845 (ops GR16:$dst, GR16:$src1, GR16:$src2),
846 "cmovbe {$src2, $dst|$dst, $src2}",
847 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
848 X86_COND_BE))]>,
849 TB, OpSize;
850def CMOVBE16rm: I<0x46, MRMSrcMem, // if <=u, GR16 = [mem16]
851 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
852 "cmovbe {$src2, $dst|$dst, $src2}",
853 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
854 X86_COND_BE))]>,
855 TB, OpSize;
856def CMOVBE32rr: I<0x46, MRMSrcReg, // if <=u, GR32 = GR32
857 (ops GR32:$dst, GR32:$src1, GR32:$src2),
858 "cmovbe {$src2, $dst|$dst, $src2}",
859 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
860 X86_COND_BE))]>,
861 TB;
862def CMOVBE32rm: I<0x46, MRMSrcMem, // if <=u, GR32 = [mem32]
863 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
864 "cmovbe {$src2, $dst|$dst, $src2}",
865 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
866 X86_COND_BE))]>,
867 TB;
868
869def CMOVA16rr : I<0x47, MRMSrcReg, // if >u, GR16 = GR16
870 (ops GR16:$dst, GR16:$src1, GR16:$src2),
871 "cmova {$src2, $dst|$dst, $src2}",
872 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
873 X86_COND_A))]>,
874 TB, OpSize;
875def CMOVA16rm : I<0x47, MRMSrcMem, // if >u, GR16 = [mem16]
876 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
877 "cmova {$src2, $dst|$dst, $src2}",
878 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
879 X86_COND_A))]>,
880 TB, OpSize;
881def CMOVA32rr : I<0x47, MRMSrcReg, // if >u, GR32 = GR32
882 (ops GR32:$dst, GR32:$src1, GR32:$src2),
883 "cmova {$src2, $dst|$dst, $src2}",
884 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
885 X86_COND_A))]>,
886 TB;
887def CMOVA32rm : I<0x47, MRMSrcMem, // if >u, GR32 = [mem32]
888 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
889 "cmova {$src2, $dst|$dst, $src2}",
890 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
891 X86_COND_A))]>,
892 TB;
893
894def CMOVL16rr : I<0x4C, MRMSrcReg, // if <s, GR16 = GR16
895 (ops GR16:$dst, GR16:$src1, GR16:$src2),
896 "cmovl {$src2, $dst|$dst, $src2}",
897 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
898 X86_COND_L))]>,
899 TB, OpSize;
900def CMOVL16rm : I<0x4C, MRMSrcMem, // if <s, GR16 = [mem16]
901 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
902 "cmovl {$src2, $dst|$dst, $src2}",
903 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
904 X86_COND_L))]>,
905 TB, OpSize;
906def CMOVL32rr : I<0x4C, MRMSrcReg, // if <s, GR32 = GR32
907 (ops GR32:$dst, GR32:$src1, GR32:$src2),
908 "cmovl {$src2, $dst|$dst, $src2}",
909 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
910 X86_COND_L))]>,
911 TB;
912def CMOVL32rm : I<0x4C, MRMSrcMem, // if <s, GR32 = [mem32]
913 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
914 "cmovl {$src2, $dst|$dst, $src2}",
915 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
916 X86_COND_L))]>,
917 TB;
918
919def CMOVGE16rr: I<0x4D, MRMSrcReg, // if >=s, GR16 = GR16
920 (ops GR16:$dst, GR16:$src1, GR16:$src2),
921 "cmovge {$src2, $dst|$dst, $src2}",
922 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
923 X86_COND_GE))]>,
924 TB, OpSize;
925def CMOVGE16rm: I<0x4D, MRMSrcMem, // if >=s, GR16 = [mem16]
926 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
927 "cmovge {$src2, $dst|$dst, $src2}",
928 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
929 X86_COND_GE))]>,
930 TB, OpSize;
931def CMOVGE32rr: I<0x4D, MRMSrcReg, // if >=s, GR32 = GR32
932 (ops GR32:$dst, GR32:$src1, GR32:$src2),
933 "cmovge {$src2, $dst|$dst, $src2}",
934 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
935 X86_COND_GE))]>,
936 TB;
937def CMOVGE32rm: I<0x4D, MRMSrcMem, // if >=s, GR32 = [mem32]
938 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
939 "cmovge {$src2, $dst|$dst, $src2}",
940 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
941 X86_COND_GE))]>,
942 TB;
943
944def CMOVLE16rr: I<0x4E, MRMSrcReg, // if <=s, GR16 = GR16
945 (ops GR16:$dst, GR16:$src1, GR16:$src2),
946 "cmovle {$src2, $dst|$dst, $src2}",
947 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
948 X86_COND_LE))]>,
949 TB, OpSize;
950def CMOVLE16rm: I<0x4E, MRMSrcMem, // if <=s, GR16 = [mem16]
951 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
952 "cmovle {$src2, $dst|$dst, $src2}",
953 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
954 X86_COND_LE))]>,
955 TB, OpSize;
956def CMOVLE32rr: I<0x4E, MRMSrcReg, // if <=s, GR32 = GR32
957 (ops GR32:$dst, GR32:$src1, GR32:$src2),
958 "cmovle {$src2, $dst|$dst, $src2}",
959 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
960 X86_COND_LE))]>,
961 TB;
962def CMOVLE32rm: I<0x4E, MRMSrcMem, // if <=s, GR32 = [mem32]
963 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
964 "cmovle {$src2, $dst|$dst, $src2}",
965 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
966 X86_COND_LE))]>,
967 TB;
968
969def CMOVG16rr : I<0x4F, MRMSrcReg, // if >s, GR16 = GR16
970 (ops GR16:$dst, GR16:$src1, GR16:$src2),
971 "cmovg {$src2, $dst|$dst, $src2}",
972 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
973 X86_COND_G))]>,
974 TB, OpSize;
975def CMOVG16rm : I<0x4F, MRMSrcMem, // if >s, GR16 = [mem16]
976 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
977 "cmovg {$src2, $dst|$dst, $src2}",
978 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
979 X86_COND_G))]>,
980 TB, OpSize;
981def CMOVG32rr : I<0x4F, MRMSrcReg, // if >s, GR32 = GR32
982 (ops GR32:$dst, GR32:$src1, GR32:$src2),
983 "cmovg {$src2, $dst|$dst, $src2}",
984 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
985 X86_COND_G))]>,
986 TB;
987def CMOVG32rm : I<0x4F, MRMSrcMem, // if >s, GR32 = [mem32]
988 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
989 "cmovg {$src2, $dst|$dst, $src2}",
990 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
991 X86_COND_G))]>,
992 TB;
993
994def CMOVS16rr : I<0x48, MRMSrcReg, // if signed, GR16 = GR16
995 (ops GR16:$dst, GR16:$src1, GR16:$src2),
996 "cmovs {$src2, $dst|$dst, $src2}",
997 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
998 X86_COND_S))]>,
999 TB, OpSize;
1000def CMOVS16rm : I<0x48, MRMSrcMem, // if signed, GR16 = [mem16]
1001 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1002 "cmovs {$src2, $dst|$dst, $src2}",
1003 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
1004 X86_COND_S))]>,
1005 TB, OpSize;
1006def CMOVS32rr : I<0x48, MRMSrcReg, // if signed, GR32 = GR32
1007 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1008 "cmovs {$src2, $dst|$dst, $src2}",
1009 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
1010 X86_COND_S))]>,
1011 TB;
1012def CMOVS32rm : I<0x48, MRMSrcMem, // if signed, GR32 = [mem32]
1013 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1014 "cmovs {$src2, $dst|$dst, $src2}",
1015 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
1016 X86_COND_S))]>,
1017 TB;
1018
1019def CMOVNS16rr: I<0x49, MRMSrcReg, // if !signed, GR16 = GR16
1020 (ops GR16:$dst, GR16:$src1, GR16:$src2),
1021 "cmovns {$src2, $dst|$dst, $src2}",
1022 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
1023 X86_COND_NS))]>,
1024 TB, OpSize;
1025def CMOVNS16rm: I<0x49, MRMSrcMem, // if !signed, GR16 = [mem16]
1026 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1027 "cmovns {$src2, $dst|$dst, $src2}",
1028 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
1029 X86_COND_NS))]>,
1030 TB, OpSize;
1031def CMOVNS32rr: I<0x49, MRMSrcReg, // if !signed, GR32 = GR32
1032 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1033 "cmovns {$src2, $dst|$dst, $src2}",
1034 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
1035 X86_COND_NS))]>,
1036 TB;
1037def CMOVNS32rm: I<0x49, MRMSrcMem, // if !signed, GR32 = [mem32]
1038 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1039 "cmovns {$src2, $dst|$dst, $src2}",
1040 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
1041 X86_COND_NS))]>,
1042 TB;
1043
1044def CMOVP16rr : I<0x4A, MRMSrcReg, // if parity, GR16 = GR16
1045 (ops GR16:$dst, GR16:$src1, GR16:$src2),
1046 "cmovp {$src2, $dst|$dst, $src2}",
1047 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
1048 X86_COND_P))]>,
1049 TB, OpSize;
1050def CMOVP16rm : I<0x4A, MRMSrcMem, // if parity, GR16 = [mem16]
1051 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1052 "cmovp {$src2, $dst|$dst, $src2}",
1053 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
1054 X86_COND_P))]>,
1055 TB, OpSize;
1056def CMOVP32rr : I<0x4A, MRMSrcReg, // if parity, GR32 = GR32
1057 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1058 "cmovp {$src2, $dst|$dst, $src2}",
1059 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
1060 X86_COND_P))]>,
1061 TB;
1062def CMOVP32rm : I<0x4A, MRMSrcMem, // if parity, GR32 = [mem32]
1063 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1064 "cmovp {$src2, $dst|$dst, $src2}",
1065 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
1066 X86_COND_P))]>,
1067 TB;
1068
1069def CMOVNP16rr : I<0x4B, MRMSrcReg, // if !parity, GR16 = GR16
1070 (ops GR16:$dst, GR16:$src1, GR16:$src2),
1071 "cmovnp {$src2, $dst|$dst, $src2}",
1072 [(set GR16:$dst, (X86cmov GR16:$src1, GR16:$src2,
1073 X86_COND_NP))]>,
1074 TB, OpSize;
1075def CMOVNP16rm : I<0x4B, MRMSrcMem, // if !parity, GR16 = [mem16]
1076 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1077 "cmovnp {$src2, $dst|$dst, $src2}",
1078 [(set GR16:$dst, (X86cmov GR16:$src1, (loadi16 addr:$src2),
1079 X86_COND_NP))]>,
1080 TB, OpSize;
1081def CMOVNP32rr : I<0x4B, MRMSrcReg, // if !parity, GR32 = GR32
1082 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1083 "cmovnp {$src2, $dst|$dst, $src2}",
1084 [(set GR32:$dst, (X86cmov GR32:$src1, GR32:$src2,
1085 X86_COND_NP))]>,
1086 TB;
1087def CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, GR32 = [mem32]
1088 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1089 "cmovnp {$src2, $dst|$dst, $src2}",
1090 [(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
1091 X86_COND_NP))]>,
1092 TB;
1093
1094
1095// unary instructions
1096let CodeSize = 2 in {
1097def NEG8r : I<0xF6, MRM3r, (ops GR8 :$dst, GR8 :$src), "neg{b} $dst",
1098 [(set GR8:$dst, (ineg GR8:$src))]>;
1099def NEG16r : I<0xF7, MRM3r, (ops GR16:$dst, GR16:$src), "neg{w} $dst",
1100 [(set GR16:$dst, (ineg GR16:$src))]>, OpSize;
1101def NEG32r : I<0xF7, MRM3r, (ops GR32:$dst, GR32:$src), "neg{l} $dst",
1102 [(set GR32:$dst, (ineg GR32:$src))]>;
1103let isTwoAddress = 0 in {
1104 def NEG8m : I<0xF6, MRM3m, (ops i8mem :$dst), "neg{b} $dst",
1105 [(store (ineg (loadi8 addr:$dst)), addr:$dst)]>;
1106 def NEG16m : I<0xF7, MRM3m, (ops i16mem:$dst), "neg{w} $dst",
1107 [(store (ineg (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1108 def NEG32m : I<0xF7, MRM3m, (ops i32mem:$dst), "neg{l} $dst",
1109 [(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
1110
1111}
1112
1113def NOT8r : I<0xF6, MRM2r, (ops GR8 :$dst, GR8 :$src), "not{b} $dst",
1114 [(set GR8:$dst, (not GR8:$src))]>;
1115def NOT16r : I<0xF7, MRM2r, (ops GR16:$dst, GR16:$src), "not{w} $dst",
1116 [(set GR16:$dst, (not GR16:$src))]>, OpSize;
1117def NOT32r : I<0xF7, MRM2r, (ops GR32:$dst, GR32:$src), "not{l} $dst",
1118 [(set GR32:$dst, (not GR32:$src))]>;
1119let isTwoAddress = 0 in {
1120 def NOT8m : I<0xF6, MRM2m, (ops i8mem :$dst), "not{b} $dst",
1121 [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
1122 def NOT16m : I<0xF7, MRM2m, (ops i16mem:$dst), "not{w} $dst",
1123 [(store (not (loadi16 addr:$dst)), addr:$dst)]>, OpSize;
1124 def NOT32m : I<0xF7, MRM2m, (ops i32mem:$dst), "not{l} $dst",
1125 [(store (not (loadi32 addr:$dst)), addr:$dst)]>;
1126}
1127} // CodeSize
1128
1129// TODO: inc/dec is slow for P4, but fast for Pentium-M.
1130let CodeSize = 2 in
1131def INC8r : I<0xFE, MRM0r, (ops GR8 :$dst, GR8 :$src), "inc{b} $dst",
1132 [(set GR8:$dst, (add GR8:$src, 1))]>;
1133let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
1134def INC16r : I<0x40, AddRegFrm, (ops GR16:$dst, GR16:$src), "inc{w} $dst",
1135 [(set GR16:$dst, (add GR16:$src, 1))]>,
1136 OpSize, Requires<[In32BitMode]>;
1137def INC32r : I<0x40, AddRegFrm, (ops GR32:$dst, GR32:$src), "inc{l} $dst",
1138 [(set GR32:$dst, (add GR32:$src, 1))]>, Requires<[In32BitMode]>;
1139}
1140let isTwoAddress = 0, CodeSize = 2 in {
1141 def INC8m : I<0xFE, MRM0m, (ops i8mem :$dst), "inc{b} $dst",
1142 [(store (add (loadi8 addr:$dst), 1), addr:$dst)]>;
1143 def INC16m : I<0xFF, MRM0m, (ops i16mem:$dst), "inc{w} $dst",
1144 [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, OpSize;
1145 def INC32m : I<0xFF, MRM0m, (ops i32mem:$dst), "inc{l} $dst",
1146 [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>;
1147}
1148
1149let CodeSize = 2 in
1150def DEC8r : I<0xFE, MRM1r, (ops GR8 :$dst, GR8 :$src), "dec{b} $dst",
1151 [(set GR8:$dst, (add GR8:$src, -1))]>;
1152let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
1153def DEC16r : I<0x48, AddRegFrm, (ops GR16:$dst, GR16:$src), "dec{w} $dst",
1154 [(set GR16:$dst, (add GR16:$src, -1))]>,
1155 OpSize, Requires<[In32BitMode]>;
1156def DEC32r : I<0x48, AddRegFrm, (ops GR32:$dst, GR32:$src), "dec{l} $dst",
1157 [(set GR32:$dst, (add GR32:$src, -1))]>, Requires<[In32BitMode]>;
1158}
1159
1160let isTwoAddress = 0, CodeSize = 2 in {
1161 def DEC8m : I<0xFE, MRM1m, (ops i8mem :$dst), "dec{b} $dst",
1162 [(store (add (loadi8 addr:$dst), -1), addr:$dst)]>;
1163 def DEC16m : I<0xFF, MRM1m, (ops i16mem:$dst), "dec{w} $dst",
1164 [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, OpSize;
1165 def DEC32m : I<0xFF, MRM1m, (ops i32mem:$dst), "dec{l} $dst",
1166 [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
1167}
1168
1169// Logical operators...
1170let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y
1171def AND8rr : I<0x20, MRMDestReg,
1172 (ops GR8 :$dst, GR8 :$src1, GR8 :$src2),
1173 "and{b} {$src2, $dst|$dst, $src2}",
1174 [(set GR8:$dst, (and GR8:$src1, GR8:$src2))]>;
1175def AND16rr : I<0x21, MRMDestReg,
1176 (ops GR16:$dst, GR16:$src1, GR16:$src2),
1177 "and{w} {$src2, $dst|$dst, $src2}",
1178 [(set GR16:$dst, (and GR16:$src1, GR16:$src2))]>, OpSize;
1179def AND32rr : I<0x21, MRMDestReg,
1180 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1181 "and{l} {$src2, $dst|$dst, $src2}",
1182 [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
1183}
1184
1185def AND8rm : I<0x22, MRMSrcMem,
1186 (ops GR8 :$dst, GR8 :$src1, i8mem :$src2),
1187 "and{b} {$src2, $dst|$dst, $src2}",
1188 [(set GR8:$dst, (and GR8:$src1, (load addr:$src2)))]>;
1189def AND16rm : I<0x23, MRMSrcMem,
1190 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1191 "and{w} {$src2, $dst|$dst, $src2}",
1192 [(set GR16:$dst, (and GR16:$src1, (load addr:$src2)))]>, OpSize;
1193def AND32rm : I<0x23, MRMSrcMem,
1194 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1195 "and{l} {$src2, $dst|$dst, $src2}",
1196 [(set GR32:$dst, (and GR32:$src1, (load addr:$src2)))]>;
1197
1198def AND8ri : Ii8<0x80, MRM4r,
1199 (ops GR8 :$dst, GR8 :$src1, i8imm :$src2),
1200 "and{b} {$src2, $dst|$dst, $src2}",
1201 [(set GR8:$dst, (and GR8:$src1, imm:$src2))]>;
1202def AND16ri : Ii16<0x81, MRM4r,
1203 (ops GR16:$dst, GR16:$src1, i16imm:$src2),
1204 "and{w} {$src2, $dst|$dst, $src2}",
1205 [(set GR16:$dst, (and GR16:$src1, imm:$src2))]>, OpSize;
1206def AND32ri : Ii32<0x81, MRM4r,
1207 (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1208 "and{l} {$src2, $dst|$dst, $src2}",
1209 [(set GR32:$dst, (and GR32:$src1, imm:$src2))]>;
1210def AND16ri8 : Ii8<0x83, MRM4r,
1211 (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
1212 "and{w} {$src2, $dst|$dst, $src2}",
1213 [(set GR16:$dst, (and GR16:$src1, i16immSExt8:$src2))]>,
1214 OpSize;
1215def AND32ri8 : Ii8<0x83, MRM4r,
1216 (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1217 "and{l} {$src2, $dst|$dst, $src2}",
1218 [(set GR32:$dst, (and GR32:$src1, i32immSExt8:$src2))]>;
1219
1220let isTwoAddress = 0 in {
1221 def AND8mr : I<0x20, MRMDestMem,
1222 (ops i8mem :$dst, GR8 :$src),
1223 "and{b} {$src, $dst|$dst, $src}",
1224 [(store (and (load addr:$dst), GR8:$src), addr:$dst)]>;
1225 def AND16mr : I<0x21, MRMDestMem,
1226 (ops i16mem:$dst, GR16:$src),
1227 "and{w} {$src, $dst|$dst, $src}",
1228 [(store (and (load addr:$dst), GR16:$src), addr:$dst)]>,
1229 OpSize;
1230 def AND32mr : I<0x21, MRMDestMem,
1231 (ops i32mem:$dst, GR32:$src),
1232 "and{l} {$src, $dst|$dst, $src}",
1233 [(store (and (load addr:$dst), GR32:$src), addr:$dst)]>;
1234 def AND8mi : Ii8<0x80, MRM4m,
1235 (ops i8mem :$dst, i8imm :$src),
1236 "and{b} {$src, $dst|$dst, $src}",
1237 [(store (and (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1238 def AND16mi : Ii16<0x81, MRM4m,
1239 (ops i16mem:$dst, i16imm:$src),
1240 "and{w} {$src, $dst|$dst, $src}",
1241 [(store (and (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1242 OpSize;
1243 def AND32mi : Ii32<0x81, MRM4m,
1244 (ops i32mem:$dst, i32imm:$src),
1245 "and{l} {$src, $dst|$dst, $src}",
1246 [(store (and (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1247 def AND16mi8 : Ii8<0x83, MRM4m,
1248 (ops i16mem:$dst, i16i8imm :$src),
1249 "and{w} {$src, $dst|$dst, $src}",
1250 [(store (and (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1251 OpSize;
1252 def AND32mi8 : Ii8<0x83, MRM4m,
1253 (ops i32mem:$dst, i32i8imm :$src),
1254 "and{l} {$src, $dst|$dst, $src}",
1255 [(store (and (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1256}
1257
1258
1259let isCommutable = 1 in { // X = OR Y, Z --> X = OR Z, Y
1260def OR8rr : I<0x08, MRMDestReg, (ops GR8 :$dst, GR8 :$src1, GR8 :$src2),
1261 "or{b} {$src2, $dst|$dst, $src2}",
1262 [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
1263def OR16rr : I<0x09, MRMDestReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
1264 "or{w} {$src2, $dst|$dst, $src2}",
1265 [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>, OpSize;
1266def OR32rr : I<0x09, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1267 "or{l} {$src2, $dst|$dst, $src2}",
1268 [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
1269}
1270def OR8rm : I<0x0A, MRMSrcMem , (ops GR8 :$dst, GR8 :$src1, i8mem :$src2),
1271 "or{b} {$src2, $dst|$dst, $src2}",
1272 [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
1273def OR16rm : I<0x0B, MRMSrcMem , (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1274 "or{w} {$src2, $dst|$dst, $src2}",
1275 [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>, OpSize;
1276def OR32rm : I<0x0B, MRMSrcMem , (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1277 "or{l} {$src2, $dst|$dst, $src2}",
1278 [(set GR32:$dst, (or GR32:$src1, (load addr:$src2)))]>;
1279
1280def OR8ri : Ii8 <0x80, MRM1r, (ops GR8 :$dst, GR8 :$src1, i8imm:$src2),
1281 "or{b} {$src2, $dst|$dst, $src2}",
1282 [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
1283def OR16ri : Ii16<0x81, MRM1r, (ops GR16:$dst, GR16:$src1, i16imm:$src2),
1284 "or{w} {$src2, $dst|$dst, $src2}",
1285 [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>, OpSize;
1286def OR32ri : Ii32<0x81, MRM1r, (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1287 "or{l} {$src2, $dst|$dst, $src2}",
1288 [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
1289
1290def OR16ri8 : Ii8<0x83, MRM1r, (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
1291 "or{w} {$src2, $dst|$dst, $src2}",
1292 [(set GR16:$dst, (or GR16:$src1, i16immSExt8:$src2))]>, OpSize;
1293def OR32ri8 : Ii8<0x83, MRM1r, (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1294 "or{l} {$src2, $dst|$dst, $src2}",
1295 [(set GR32:$dst, (or GR32:$src1, i32immSExt8:$src2))]>;
1296let isTwoAddress = 0 in {
1297 def OR8mr : I<0x08, MRMDestMem, (ops i8mem:$dst, GR8:$src),
1298 "or{b} {$src, $dst|$dst, $src}",
1299 [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
1300 def OR16mr : I<0x09, MRMDestMem, (ops i16mem:$dst, GR16:$src),
1301 "or{w} {$src, $dst|$dst, $src}",
1302 [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>, OpSize;
1303 def OR32mr : I<0x09, MRMDestMem, (ops i32mem:$dst, GR32:$src),
1304 "or{l} {$src, $dst|$dst, $src}",
1305 [(store (or (load addr:$dst), GR32:$src), addr:$dst)]>;
1306 def OR8mi : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src),
1307 "or{b} {$src, $dst|$dst, $src}",
1308 [(store (or (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1309 def OR16mi : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src),
1310 "or{w} {$src, $dst|$dst, $src}",
1311 [(store (or (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1312 OpSize;
1313 def OR32mi : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src),
1314 "or{l} {$src, $dst|$dst, $src}",
1315 [(store (or (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1316 def OR16mi8 : Ii8<0x83, MRM1m, (ops i16mem:$dst, i16i8imm:$src),
1317 "or{w} {$src, $dst|$dst, $src}",
1318 [(store (or (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1319 OpSize;
1320 def OR32mi8 : Ii8<0x83, MRM1m, (ops i32mem:$dst, i32i8imm:$src),
1321 "or{l} {$src, $dst|$dst, $src}",
1322 [(store (or (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1323}
1324
1325
1326let isCommutable = 1 in { // X = XOR Y, Z --> X = XOR Z, Y
1327def XOR8rr : I<0x30, MRMDestReg,
1328 (ops GR8 :$dst, GR8 :$src1, GR8 :$src2),
1329 "xor{b} {$src2, $dst|$dst, $src2}",
1330 [(set GR8:$dst, (xor GR8:$src1, GR8:$src2))]>;
1331def XOR16rr : I<0x31, MRMDestReg,
1332 (ops GR16:$dst, GR16:$src1, GR16:$src2),
1333 "xor{w} {$src2, $dst|$dst, $src2}",
1334 [(set GR16:$dst, (xor GR16:$src1, GR16:$src2))]>, OpSize;
1335def XOR32rr : I<0x31, MRMDestReg,
1336 (ops GR32:$dst, GR32:$src1, GR32:$src2),
1337 "xor{l} {$src2, $dst|$dst, $src2}",
1338 [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
1339}
1340
1341def XOR8rm : I<0x32, MRMSrcMem ,
1342 (ops GR8 :$dst, GR8:$src1, i8mem :$src2),
1343 "xor{b} {$src2, $dst|$dst, $src2}",
1344 [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2)))]>;
1345def XOR16rm : I<0x33, MRMSrcMem ,
1346 (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1347 "xor{w} {$src2, $dst|$dst, $src2}",
1348 [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2)))]>, OpSize;
1349def XOR32rm : I<0x33, MRMSrcMem ,
1350 (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1351 "xor{l} {$src2, $dst|$dst, $src2}",
1352 [(set GR32:$dst, (xor GR32:$src1, (load addr:$src2)))]>;
1353
1354def XOR8ri : Ii8<0x80, MRM6r,
1355 (ops GR8:$dst, GR8:$src1, i8imm:$src2),
1356 "xor{b} {$src2, $dst|$dst, $src2}",
1357 [(set GR8:$dst, (xor GR8:$src1, imm:$src2))]>;
1358def XOR16ri : Ii16<0x81, MRM6r,
1359 (ops GR16:$dst, GR16:$src1, i16imm:$src2),
1360 "xor{w} {$src2, $dst|$dst, $src2}",
1361 [(set GR16:$dst, (xor GR16:$src1, imm:$src2))]>, OpSize;
1362def XOR32ri : Ii32<0x81, MRM6r,
1363 (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1364 "xor{l} {$src2, $dst|$dst, $src2}",
1365 [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
1366def XOR16ri8 : Ii8<0x83, MRM6r,
1367 (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
1368 "xor{w} {$src2, $dst|$dst, $src2}",
1369 [(set GR16:$dst, (xor GR16:$src1, i16immSExt8:$src2))]>,
1370 OpSize;
1371def XOR32ri8 : Ii8<0x83, MRM6r,
1372 (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1373 "xor{l} {$src2, $dst|$dst, $src2}",
1374 [(set GR32:$dst, (xor GR32:$src1, i32immSExt8:$src2))]>;
1375let isTwoAddress = 0 in {
1376 def XOR8mr : I<0x30, MRMDestMem,
1377 (ops i8mem :$dst, GR8 :$src),
1378 "xor{b} {$src, $dst|$dst, $src}",
1379 [(store (xor (load addr:$dst), GR8:$src), addr:$dst)]>;
1380 def XOR16mr : I<0x31, MRMDestMem,
1381 (ops i16mem:$dst, GR16:$src),
1382 "xor{w} {$src, $dst|$dst, $src}",
1383 [(store (xor (load addr:$dst), GR16:$src), addr:$dst)]>,
1384 OpSize;
1385 def XOR32mr : I<0x31, MRMDestMem,
1386 (ops i32mem:$dst, GR32:$src),
1387 "xor{l} {$src, $dst|$dst, $src}",
1388 [(store (xor (load addr:$dst), GR32:$src), addr:$dst)]>;
1389 def XOR8mi : Ii8<0x80, MRM6m,
1390 (ops i8mem :$dst, i8imm :$src),
1391 "xor{b} {$src, $dst|$dst, $src}",
1392 [(store (xor (loadi8 addr:$dst), imm:$src), addr:$dst)]>;
1393 def XOR16mi : Ii16<0x81, MRM6m,
1394 (ops i16mem:$dst, i16imm:$src),
1395 "xor{w} {$src, $dst|$dst, $src}",
1396 [(store (xor (loadi16 addr:$dst), imm:$src), addr:$dst)]>,
1397 OpSize;
1398 def XOR32mi : Ii32<0x81, MRM6m,
1399 (ops i32mem:$dst, i32imm:$src),
1400 "xor{l} {$src, $dst|$dst, $src}",
1401 [(store (xor (loadi32 addr:$dst), imm:$src), addr:$dst)]>;
1402 def XOR16mi8 : Ii8<0x83, MRM6m,
1403 (ops i16mem:$dst, i16i8imm :$src),
1404 "xor{w} {$src, $dst|$dst, $src}",
1405 [(store (xor (load addr:$dst), i16immSExt8:$src), addr:$dst)]>,
1406 OpSize;
1407 def XOR32mi8 : Ii8<0x83, MRM6m,
1408 (ops i32mem:$dst, i32i8imm :$src),
1409 "xor{l} {$src, $dst|$dst, $src}",
1410 [(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
1411}
1412
1413// Shift instructions
1414def SHL8rCL : I<0xD2, MRM4r, (ops GR8 :$dst, GR8 :$src),
1415 "shl{b} {%cl, $dst|$dst, %CL}",
1416 [(set GR8:$dst, (shl GR8:$src, CL))]>, Imp<[CL],[]>;
1417def SHL16rCL : I<0xD3, MRM4r, (ops GR16:$dst, GR16:$src),
1418 "shl{w} {%cl, $dst|$dst, %CL}",
1419 [(set GR16:$dst, (shl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1420def SHL32rCL : I<0xD3, MRM4r, (ops GR32:$dst, GR32:$src),
1421 "shl{l} {%cl, $dst|$dst, %CL}",
1422 [(set GR32:$dst, (shl GR32:$src, CL))]>, Imp<[CL],[]>;
1423
1424def SHL8ri : Ii8<0xC0, MRM4r, (ops GR8 :$dst, GR8 :$src1, i8imm:$src2),
1425 "shl{b} {$src2, $dst|$dst, $src2}",
1426 [(set GR8:$dst, (shl GR8:$src1, (i8 imm:$src2)))]>;
1427let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1428def SHL16ri : Ii8<0xC1, MRM4r, (ops GR16:$dst, GR16:$src1, i8imm:$src2),
1429 "shl{w} {$src2, $dst|$dst, $src2}",
1430 [(set GR16:$dst, (shl GR16:$src1, (i8 imm:$src2)))]>, OpSize;
1431def SHL32ri : Ii8<0xC1, MRM4r, (ops GR32:$dst, GR32:$src1, i8imm:$src2),
1432 "shl{l} {$src2, $dst|$dst, $src2}",
1433 [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))]>;
1434}
1435
1436// Shift left by one. Not used because (add x, x) is slightly cheaper.
1437def SHL8r1 : I<0xD0, MRM4r, (ops GR8 :$dst, GR8 :$src1),
1438 "shl{b} $dst", []>;
1439def SHL16r1 : I<0xD1, MRM4r, (ops GR16:$dst, GR16:$src1),
1440 "shl{w} $dst", []>, OpSize;
1441def SHL32r1 : I<0xD1, MRM4r, (ops GR32:$dst, GR32:$src1),
1442 "shl{l} $dst", []>;
1443
1444let isTwoAddress = 0 in {
1445 def SHL8mCL : I<0xD2, MRM4m, (ops i8mem :$dst),
1446 "shl{b} {%cl, $dst|$dst, %CL}",
1447 [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
1448 Imp<[CL],[]>;
1449 def SHL16mCL : I<0xD3, MRM4m, (ops i16mem:$dst),
1450 "shl{w} {%cl, $dst|$dst, %CL}",
1451 [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
1452 Imp<[CL],[]>, OpSize;
1453 def SHL32mCL : I<0xD3, MRM4m, (ops i32mem:$dst),
1454 "shl{l} {%cl, $dst|$dst, %CL}",
1455 [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
1456 Imp<[CL],[]>;
1457 def SHL8mi : Ii8<0xC0, MRM4m, (ops i8mem :$dst, i8imm:$src),
1458 "shl{b} {$src, $dst|$dst, $src}",
1459 [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1460 def SHL16mi : Ii8<0xC1, MRM4m, (ops i16mem:$dst, i8imm:$src),
1461 "shl{w} {$src, $dst|$dst, $src}",
1462 [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1463 OpSize;
1464 def SHL32mi : Ii8<0xC1, MRM4m, (ops i32mem:$dst, i8imm:$src),
1465 "shl{l} {$src, $dst|$dst, $src}",
1466 [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1467
1468 // Shift by 1
1469 def SHL8m1 : I<0xD0, MRM4m, (ops i8mem :$dst),
1470 "shl{b} $dst",
1471 [(store (shl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
1472 def SHL16m1 : I<0xD1, MRM4m, (ops i16mem:$dst),
1473 "shl{w} $dst",
1474 [(store (shl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
1475 OpSize;
1476 def SHL32m1 : I<0xD1, MRM4m, (ops i32mem:$dst),
1477 "shl{l} $dst",
1478 [(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
1479}
1480
1481def SHR8rCL : I<0xD2, MRM5r, (ops GR8 :$dst, GR8 :$src),
1482 "shr{b} {%cl, $dst|$dst, %CL}",
1483 [(set GR8:$dst, (srl GR8:$src, CL))]>, Imp<[CL],[]>;
1484def SHR16rCL : I<0xD3, MRM5r, (ops GR16:$dst, GR16:$src),
1485 "shr{w} {%cl, $dst|$dst, %CL}",
1486 [(set GR16:$dst, (srl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1487def SHR32rCL : I<0xD3, MRM5r, (ops GR32:$dst, GR32:$src),
1488 "shr{l} {%cl, $dst|$dst, %CL}",
1489 [(set GR32:$dst, (srl GR32:$src, CL))]>, Imp<[CL],[]>;
1490
1491def SHR8ri : Ii8<0xC0, MRM5r, (ops GR8:$dst, GR8:$src1, i8imm:$src2),
1492 "shr{b} {$src2, $dst|$dst, $src2}",
1493 [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))]>;
1494def SHR16ri : Ii8<0xC1, MRM5r, (ops GR16:$dst, GR16:$src1, i8imm:$src2),
1495 "shr{w} {$src2, $dst|$dst, $src2}",
1496 [(set GR16:$dst, (srl GR16:$src1, (i8 imm:$src2)))]>, OpSize;
1497def SHR32ri : Ii8<0xC1, MRM5r, (ops GR32:$dst, GR32:$src1, i8imm:$src2),
1498 "shr{l} {$src2, $dst|$dst, $src2}",
1499 [(set GR32:$dst, (srl GR32:$src1, (i8 imm:$src2)))]>;
1500
1501// Shift by 1
1502def SHR8r1 : I<0xD0, MRM5r, (ops GR8:$dst, GR8:$src1),
1503 "shr{b} $dst",
1504 [(set GR8:$dst, (srl GR8:$src1, (i8 1)))]>;
1505def SHR16r1 : I<0xD1, MRM5r, (ops GR16:$dst, GR16:$src1),
1506 "shr{w} $dst",
1507 [(set GR16:$dst, (srl GR16:$src1, (i8 1)))]>, OpSize;
1508def SHR32r1 : I<0xD1, MRM5r, (ops GR32:$dst, GR32:$src1),
1509 "shr{l} $dst",
1510 [(set GR32:$dst, (srl GR32:$src1, (i8 1)))]>;
1511
1512let isTwoAddress = 0 in {
1513 def SHR8mCL : I<0xD2, MRM5m, (ops i8mem :$dst),
1514 "shr{b} {%cl, $dst|$dst, %CL}",
1515 [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
1516 Imp<[CL],[]>;
1517 def SHR16mCL : I<0xD3, MRM5m, (ops i16mem:$dst),
1518 "shr{w} {%cl, $dst|$dst, %CL}",
1519 [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
1520 Imp<[CL],[]>, OpSize;
1521 def SHR32mCL : I<0xD3, MRM5m, (ops i32mem:$dst),
1522 "shr{l} {%cl, $dst|$dst, %CL}",
1523 [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
1524 Imp<[CL],[]>;
1525 def SHR8mi : Ii8<0xC0, MRM5m, (ops i8mem :$dst, i8imm:$src),
1526 "shr{b} {$src, $dst|$dst, $src}",
1527 [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1528 def SHR16mi : Ii8<0xC1, MRM5m, (ops i16mem:$dst, i8imm:$src),
1529 "shr{w} {$src, $dst|$dst, $src}",
1530 [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1531 OpSize;
1532 def SHR32mi : Ii8<0xC1, MRM5m, (ops i32mem:$dst, i8imm:$src),
1533 "shr{l} {$src, $dst|$dst, $src}",
1534 [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1535
1536 // Shift by 1
1537 def SHR8m1 : I<0xD0, MRM5m, (ops i8mem :$dst),
1538 "shr{b} $dst",
1539 [(store (srl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
1540 def SHR16m1 : I<0xD1, MRM5m, (ops i16mem:$dst),
1541 "shr{w} $dst",
1542 [(store (srl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,OpSize;
1543 def SHR32m1 : I<0xD1, MRM5m, (ops i32mem:$dst),
1544 "shr{l} $dst",
1545 [(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
1546}
1547
1548def SAR8rCL : I<0xD2, MRM7r, (ops GR8 :$dst, GR8 :$src),
1549 "sar{b} {%cl, $dst|$dst, %CL}",
1550 [(set GR8:$dst, (sra GR8:$src, CL))]>, Imp<[CL],[]>;
1551def SAR16rCL : I<0xD3, MRM7r, (ops GR16:$dst, GR16:$src),
1552 "sar{w} {%cl, $dst|$dst, %CL}",
1553 [(set GR16:$dst, (sra GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1554def SAR32rCL : I<0xD3, MRM7r, (ops GR32:$dst, GR32:$src),
1555 "sar{l} {%cl, $dst|$dst, %CL}",
1556 [(set GR32:$dst, (sra GR32:$src, CL))]>, Imp<[CL],[]>;
1557
1558def SAR8ri : Ii8<0xC0, MRM7r, (ops GR8 :$dst, GR8 :$src1, i8imm:$src2),
1559 "sar{b} {$src2, $dst|$dst, $src2}",
1560 [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))]>;
1561def SAR16ri : Ii8<0xC1, MRM7r, (ops GR16:$dst, GR16:$src1, i8imm:$src2),
1562 "sar{w} {$src2, $dst|$dst, $src2}",
1563 [(set GR16:$dst, (sra GR16:$src1, (i8 imm:$src2)))]>,
1564 OpSize;
1565def SAR32ri : Ii8<0xC1, MRM7r, (ops GR32:$dst, GR32:$src1, i8imm:$src2),
1566 "sar{l} {$src2, $dst|$dst, $src2}",
1567 [(set GR32:$dst, (sra GR32:$src1, (i8 imm:$src2)))]>;
1568
1569// Shift by 1
1570def SAR8r1 : I<0xD0, MRM7r, (ops GR8 :$dst, GR8 :$src1),
1571 "sar{b} $dst",
1572 [(set GR8:$dst, (sra GR8:$src1, (i8 1)))]>;
1573def SAR16r1 : I<0xD1, MRM7r, (ops GR16:$dst, GR16:$src1),
1574 "sar{w} $dst",
1575 [(set GR16:$dst, (sra GR16:$src1, (i8 1)))]>, OpSize;
1576def SAR32r1 : I<0xD1, MRM7r, (ops GR32:$dst, GR32:$src1),
1577 "sar{l} $dst",
1578 [(set GR32:$dst, (sra GR32:$src1, (i8 1)))]>;
1579
1580let isTwoAddress = 0 in {
1581 def SAR8mCL : I<0xD2, MRM7m, (ops i8mem :$dst),
1582 "sar{b} {%cl, $dst|$dst, %CL}",
1583 [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
1584 Imp<[CL],[]>;
1585 def SAR16mCL : I<0xD3, MRM7m, (ops i16mem:$dst),
1586 "sar{w} {%cl, $dst|$dst, %CL}",
1587 [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
1588 Imp<[CL],[]>, OpSize;
1589 def SAR32mCL : I<0xD3, MRM7m, (ops i32mem:$dst),
1590 "sar{l} {%cl, $dst|$dst, %CL}",
1591 [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
1592 Imp<[CL],[]>;
1593 def SAR8mi : Ii8<0xC0, MRM7m, (ops i8mem :$dst, i8imm:$src),
1594 "sar{b} {$src, $dst|$dst, $src}",
1595 [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1596 def SAR16mi : Ii8<0xC1, MRM7m, (ops i16mem:$dst, i8imm:$src),
1597 "sar{w} {$src, $dst|$dst, $src}",
1598 [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1599 OpSize;
1600 def SAR32mi : Ii8<0xC1, MRM7m, (ops i32mem:$dst, i8imm:$src),
1601 "sar{l} {$src, $dst|$dst, $src}",
1602 [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1603
1604 // Shift by 1
1605 def SAR8m1 : I<0xD0, MRM7m, (ops i8mem :$dst),
1606 "sar{b} $dst",
1607 [(store (sra (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
1608 def SAR16m1 : I<0xD1, MRM7m, (ops i16mem:$dst),
1609 "sar{w} $dst",
1610 [(store (sra (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
1611 OpSize;
1612 def SAR32m1 : I<0xD1, MRM7m, (ops i32mem:$dst),
1613 "sar{l} $dst",
1614 [(store (sra (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
1615}
1616
1617// Rotate instructions
1618// FIXME: provide shorter instructions when imm8 == 1
1619def ROL8rCL : I<0xD2, MRM0r, (ops GR8 :$dst, GR8 :$src),
1620 "rol{b} {%cl, $dst|$dst, %CL}",
1621 [(set GR8:$dst, (rotl GR8:$src, CL))]>, Imp<[CL],[]>;
1622def ROL16rCL : I<0xD3, MRM0r, (ops GR16:$dst, GR16:$src),
1623 "rol{w} {%cl, $dst|$dst, %CL}",
1624 [(set GR16:$dst, (rotl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1625def ROL32rCL : I<0xD3, MRM0r, (ops GR32:$dst, GR32:$src),
1626 "rol{l} {%cl, $dst|$dst, %CL}",
1627 [(set GR32:$dst, (rotl GR32:$src, CL))]>, Imp<[CL],[]>;
1628
1629def ROL8ri : Ii8<0xC0, MRM0r, (ops GR8 :$dst, GR8 :$src1, i8imm:$src2),
1630 "rol{b} {$src2, $dst|$dst, $src2}",
1631 [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))]>;
1632def ROL16ri : Ii8<0xC1, MRM0r, (ops GR16:$dst, GR16:$src1, i8imm:$src2),
1633 "rol{w} {$src2, $dst|$dst, $src2}",
1634 [(set GR16:$dst, (rotl GR16:$src1, (i8 imm:$src2)))]>, OpSize;
1635def ROL32ri : Ii8<0xC1, MRM0r, (ops GR32:$dst, GR32:$src1, i8imm:$src2),
1636 "rol{l} {$src2, $dst|$dst, $src2}",
1637 [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$src2)))]>;
1638
1639// Rotate by 1
1640def ROL8r1 : I<0xD0, MRM0r, (ops GR8 :$dst, GR8 :$src1),
1641 "rol{b} $dst",
1642 [(set GR8:$dst, (rotl GR8:$src1, (i8 1)))]>;
1643def ROL16r1 : I<0xD1, MRM0r, (ops GR16:$dst, GR16:$src1),
1644 "rol{w} $dst",
1645 [(set GR16:$dst, (rotl GR16:$src1, (i8 1)))]>, OpSize;
1646def ROL32r1 : I<0xD1, MRM0r, (ops GR32:$dst, GR32:$src1),
1647 "rol{l} $dst",
1648 [(set GR32:$dst, (rotl GR32:$src1, (i8 1)))]>;
1649
1650let isTwoAddress = 0 in {
1651 def ROL8mCL : I<0xD2, MRM0m, (ops i8mem :$dst),
1652 "rol{b} {%cl, $dst|$dst, %CL}",
1653 [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>,
1654 Imp<[CL],[]>;
1655 def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst),
1656 "rol{w} {%cl, $dst|$dst, %CL}",
1657 [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>,
1658 Imp<[CL],[]>, OpSize;
1659 def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst),
1660 "rol{l} {%cl, $dst|$dst, %CL}",
1661 [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>,
1662 Imp<[CL],[]>;
1663 def ROL8mi : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src),
1664 "rol{b} {$src, $dst|$dst, $src}",
1665 [(store (rotl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1666 def ROL16mi : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src),
1667 "rol{w} {$src, $dst|$dst, $src}",
1668 [(store (rotl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1669 OpSize;
1670 def ROL32mi : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src),
1671 "rol{l} {$src, $dst|$dst, $src}",
1672 [(store (rotl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1673
1674 // Rotate by 1
1675 def ROL8m1 : I<0xD0, MRM0m, (ops i8mem :$dst),
1676 "rol{b} $dst",
1677 [(store (rotl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
1678 def ROL16m1 : I<0xD1, MRM0m, (ops i16mem:$dst),
1679 "rol{w} $dst",
1680 [(store (rotl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
1681 OpSize;
1682 def ROL32m1 : I<0xD1, MRM0m, (ops i32mem:$dst),
1683 "rol{l} $dst",
1684 [(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
1685}
1686
1687def ROR8rCL : I<0xD2, MRM1r, (ops GR8 :$dst, GR8 :$src),
1688 "ror{b} {%cl, $dst|$dst, %CL}",
1689 [(set GR8:$dst, (rotr GR8:$src, CL))]>, Imp<[CL],[]>;
1690def ROR16rCL : I<0xD3, MRM1r, (ops GR16:$dst, GR16:$src),
1691 "ror{w} {%cl, $dst|$dst, %CL}",
1692 [(set GR16:$dst, (rotr GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
1693def ROR32rCL : I<0xD3, MRM1r, (ops GR32:$dst, GR32:$src),
1694 "ror{l} {%cl, $dst|$dst, %CL}",
1695 [(set GR32:$dst, (rotr GR32:$src, CL))]>, Imp<[CL],[]>;
1696
1697def ROR8ri : Ii8<0xC0, MRM1r, (ops GR8 :$dst, GR8 :$src1, i8imm:$src2),
1698 "ror{b} {$src2, $dst|$dst, $src2}",
1699 [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))]>;
1700def ROR16ri : Ii8<0xC1, MRM1r, (ops GR16:$dst, GR16:$src1, i8imm:$src2),
1701 "ror{w} {$src2, $dst|$dst, $src2}",
1702 [(set GR16:$dst, (rotr GR16:$src1, (i8 imm:$src2)))]>, OpSize;
1703def ROR32ri : Ii8<0xC1, MRM1r, (ops GR32:$dst, GR32:$src1, i8imm:$src2),
1704 "ror{l} {$src2, $dst|$dst, $src2}",
1705 [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$src2)))]>;
1706
1707// Rotate by 1
1708def ROR8r1 : I<0xD0, MRM1r, (ops GR8 :$dst, GR8 :$src1),
1709 "ror{b} $dst",
1710 [(set GR8:$dst, (rotr GR8:$src1, (i8 1)))]>;
1711def ROR16r1 : I<0xD1, MRM1r, (ops GR16:$dst, GR16:$src1),
1712 "ror{w} $dst",
1713 [(set GR16:$dst, (rotr GR16:$src1, (i8 1)))]>, OpSize;
1714def ROR32r1 : I<0xD1, MRM1r, (ops GR32:$dst, GR32:$src1),
1715 "ror{l} $dst",
1716 [(set GR32:$dst, (rotr GR32:$src1, (i8 1)))]>;
1717
1718let isTwoAddress = 0 in {
1719 def ROR8mCL : I<0xD2, MRM1m, (ops i8mem :$dst),
1720 "ror{b} {%cl, $dst|$dst, %CL}",
1721 [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>,
1722 Imp<[CL],[]>;
1723 def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst),
1724 "ror{w} {%cl, $dst|$dst, %CL}",
1725 [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>,
1726 Imp<[CL],[]>, OpSize;
1727 def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst),
1728 "ror{l} {%cl, $dst|$dst, %CL}",
1729 [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>,
1730 Imp<[CL],[]>;
1731 def ROR8mi : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src),
1732 "ror{b} {$src, $dst|$dst, $src}",
1733 [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1734 def ROR16mi : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src),
1735 "ror{w} {$src, $dst|$dst, $src}",
1736 [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
1737 OpSize;
1738 def ROR32mi : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src),
1739 "ror{l} {$src, $dst|$dst, $src}",
1740 [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1741
1742 // Rotate by 1
1743 def ROR8m1 : I<0xD0, MRM1m, (ops i8mem :$dst),
1744 "ror{b} $dst",
1745 [(store (rotr (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
1746 def ROR16m1 : I<0xD1, MRM1m, (ops i16mem:$dst),
1747 "ror{w} $dst",
1748 [(store (rotr (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
1749 OpSize;
1750 def ROR32m1 : I<0xD1, MRM1m, (ops i32mem:$dst),
1751 "ror{l} $dst",
1752 [(store (rotr (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
1753}
1754
1755
1756
1757// Double shift instructions (generalizations of rotate)
1758def SHLD32rrCL : I<0xA5, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1759 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1760 [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))]>,
1761 Imp<[CL],[]>, TB;
1762def SHRD32rrCL : I<0xAD, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1763 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1764 [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))]>,
1765 Imp<[CL],[]>, TB;
1766def SHLD16rrCL : I<0xA5, MRMDestReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
1767 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1768 [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))]>,
1769 Imp<[CL],[]>, TB, OpSize;
1770def SHRD16rrCL : I<0xAD, MRMDestReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
1771 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1772 [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))]>,
1773 Imp<[CL],[]>, TB, OpSize;
1774
1775let isCommutable = 1 in { // These instructions commute to each other.
1776def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
1777 (ops GR32:$dst, GR32:$src1, GR32:$src2, i8imm:$src3),
1778 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1779 [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2,
1780 (i8 imm:$src3)))]>,
1781 TB;
1782def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
1783 (ops GR32:$dst, GR32:$src1, GR32:$src2, i8imm:$src3),
1784 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1785 [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2,
1786 (i8 imm:$src3)))]>,
1787 TB;
1788def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
1789 (ops GR16:$dst, GR16:$src1, GR16:$src2, i8imm:$src3),
1790 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1791 [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2,
1792 (i8 imm:$src3)))]>,
1793 TB, OpSize;
1794def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
1795 (ops GR16:$dst, GR16:$src1, GR16:$src2, i8imm:$src3),
1796 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1797 [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2,
1798 (i8 imm:$src3)))]>,
1799 TB, OpSize;
1800}
1801
1802let isTwoAddress = 0 in {
1803 def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
1804 "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1805 [(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL),
1806 addr:$dst)]>,
1807 Imp<[CL],[]>, TB;
1808 def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
1809 "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
1810 [(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL),
1811 addr:$dst)]>,
1812 Imp<[CL],[]>, TB;
1813 def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
1814 (ops i32mem:$dst, GR32:$src2, i8imm:$src3),
1815 "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1816 [(store (X86shld (loadi32 addr:$dst), GR32:$src2,
1817 (i8 imm:$src3)), addr:$dst)]>,
1818 TB;
1819 def SHRD32mri8 : Ii8<0xAC, MRMDestMem,
1820 (ops i32mem:$dst, GR32:$src2, i8imm:$src3),
1821 "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
1822 [(store (X86shrd (loadi32 addr:$dst), GR32:$src2,
1823 (i8 imm:$src3)), addr:$dst)]>,
1824 TB;
1825
1826 def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, GR16:$src2),
1827 "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1828 [(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL),
1829 addr:$dst)]>,
1830 Imp<[CL],[]>, TB, OpSize;
1831 def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, GR16:$src2),
1832 "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
1833 [(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL),
1834 addr:$dst)]>,
1835 Imp<[CL],[]>, TB, OpSize;
1836 def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
1837 (ops i16mem:$dst, GR16:$src2, i8imm:$src3),
1838 "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1839 [(store (X86shld (loadi16 addr:$dst), GR16:$src2,
1840 (i8 imm:$src3)), addr:$dst)]>,
1841 TB, OpSize;
1842 def SHRD16mri8 : Ii8<0xAC, MRMDestMem,
1843 (ops i16mem:$dst, GR16:$src2, i8imm:$src3),
1844 "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
1845 [(store (X86shrd (loadi16 addr:$dst), GR16:$src2,
1846 (i8 imm:$src3)), addr:$dst)]>,
1847 TB, OpSize;
1848}
1849
1850
1851// Arithmetic.
1852let isCommutable = 1 in { // X = ADD Y, Z --> X = ADD Z, Y
1853def ADD8rr : I<0x00, MRMDestReg, (ops GR8 :$dst, GR8 :$src1, GR8 :$src2),
1854 "add{b} {$src2, $dst|$dst, $src2}",
1855 [(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>;
1856let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1857def ADD16rr : I<0x01, MRMDestReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
1858 "add{w} {$src2, $dst|$dst, $src2}",
1859 [(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>, OpSize;
1860def ADD32rr : I<0x01, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1861 "add{l} {$src2, $dst|$dst, $src2}",
1862 [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
1863} // end isConvertibleToThreeAddress
1864} // end isCommutable
1865def ADD8rm : I<0x02, MRMSrcMem, (ops GR8 :$dst, GR8 :$src1, i8mem :$src2),
1866 "add{b} {$src2, $dst|$dst, $src2}",
1867 [(set GR8:$dst, (add GR8:$src1, (load addr:$src2)))]>;
1868def ADD16rm : I<0x03, MRMSrcMem, (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1869 "add{w} {$src2, $dst|$dst, $src2}",
1870 [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>, OpSize;
1871def ADD32rm : I<0x03, MRMSrcMem, (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1872 "add{l} {$src2, $dst|$dst, $src2}",
1873 [(set GR32:$dst, (add GR32:$src1, (load addr:$src2)))]>;
1874
1875def ADD8ri : Ii8<0x80, MRM0r, (ops GR8:$dst, GR8:$src1, i8imm:$src2),
1876 "add{b} {$src2, $dst|$dst, $src2}",
1877 [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>;
1878
1879let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
1880def ADD16ri : Ii16<0x81, MRM0r, (ops GR16:$dst, GR16:$src1, i16imm:$src2),
1881 "add{w} {$src2, $dst|$dst, $src2}",
1882 [(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize;
1883def ADD32ri : Ii32<0x81, MRM0r, (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1884 "add{l} {$src2, $dst|$dst, $src2}",
1885 [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>;
1886def ADD16ri8 : Ii8<0x83, MRM0r, (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
1887 "add{w} {$src2, $dst|$dst, $src2}",
1888 [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>,
1889 OpSize;
1890def ADD32ri8 : Ii8<0x83, MRM0r, (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1891 "add{l} {$src2, $dst|$dst, $src2}",
1892 [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>;
1893}
1894
1895let isTwoAddress = 0 in {
1896 def ADD8mr : I<0x00, MRMDestMem, (ops i8mem :$dst, GR8 :$src2),
1897 "add{b} {$src2, $dst|$dst, $src2}",
1898 [(store (add (load addr:$dst), GR8:$src2), addr:$dst)]>;
1899 def ADD16mr : I<0x01, MRMDestMem, (ops i16mem:$dst, GR16:$src2),
1900 "add{w} {$src2, $dst|$dst, $src2}",
1901 [(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>,
1902 OpSize;
1903 def ADD32mr : I<0x01, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
1904 "add{l} {$src2, $dst|$dst, $src2}",
1905 [(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>;
1906 def ADD8mi : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2),
1907 "add{b} {$src2, $dst|$dst, $src2}",
1908 [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
1909 def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2),
1910 "add{w} {$src2, $dst|$dst, $src2}",
1911 [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
1912 OpSize;
1913 def ADD32mi : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2),
1914 "add{l} {$src2, $dst|$dst, $src2}",
1915 [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1916 def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i16i8imm :$src2),
1917 "add{w} {$src2, $dst|$dst, $src2}",
1918 [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
1919 OpSize;
1920 def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i32i8imm :$src2),
1921 "add{l} {$src2, $dst|$dst, $src2}",
1922 [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1923}
1924
1925let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y
1926def ADC32rr : I<0x11, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1927 "adc{l} {$src2, $dst|$dst, $src2}",
1928 [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>;
1929}
1930def ADC32rm : I<0x13, MRMSrcMem , (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1931 "adc{l} {$src2, $dst|$dst, $src2}",
1932 [(set GR32:$dst, (adde GR32:$src1, (load addr:$src2)))]>;
1933def ADC32ri : Ii32<0x81, MRM2r, (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1934 "adc{l} {$src2, $dst|$dst, $src2}",
1935 [(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>;
1936def ADC32ri8 : Ii8<0x83, MRM2r, (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1937 "adc{l} {$src2, $dst|$dst, $src2}",
1938 [(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2))]>;
1939
1940let isTwoAddress = 0 in {
1941 def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
1942 "adc{l} {$src2, $dst|$dst, $src2}",
1943 [(store (adde (load addr:$dst), GR32:$src2), addr:$dst)]>;
1944 def ADC32mi : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
1945 "adc{l} {$src2, $dst|$dst, $src2}",
1946 [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
1947 def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
1948 "adc{l} {$src2, $dst|$dst, $src2}",
1949 [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
1950}
1951
1952def SUB8rr : I<0x28, MRMDestReg, (ops GR8 :$dst, GR8 :$src1, GR8 :$src2),
1953 "sub{b} {$src2, $dst|$dst, $src2}",
1954 [(set GR8:$dst, (sub GR8:$src1, GR8:$src2))]>;
1955def SUB16rr : I<0x29, MRMDestReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
1956 "sub{w} {$src2, $dst|$dst, $src2}",
1957 [(set GR16:$dst, (sub GR16:$src1, GR16:$src2))]>, OpSize;
1958def SUB32rr : I<0x29, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
1959 "sub{l} {$src2, $dst|$dst, $src2}",
1960 [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
1961def SUB8rm : I<0x2A, MRMSrcMem, (ops GR8 :$dst, GR8 :$src1, i8mem :$src2),
1962 "sub{b} {$src2, $dst|$dst, $src2}",
1963 [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2)))]>;
1964def SUB16rm : I<0x2B, MRMSrcMem, (ops GR16:$dst, GR16:$src1, i16mem:$src2),
1965 "sub{w} {$src2, $dst|$dst, $src2}",
1966 [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2)))]>, OpSize;
1967def SUB32rm : I<0x2B, MRMSrcMem, (ops GR32:$dst, GR32:$src1, i32mem:$src2),
1968 "sub{l} {$src2, $dst|$dst, $src2}",
1969 [(set GR32:$dst, (sub GR32:$src1, (load addr:$src2)))]>;
1970
1971def SUB8ri : Ii8 <0x80, MRM5r, (ops GR8:$dst, GR8:$src1, i8imm:$src2),
1972 "sub{b} {$src2, $dst|$dst, $src2}",
1973 [(set GR8:$dst, (sub GR8:$src1, imm:$src2))]>;
1974def SUB16ri : Ii16<0x81, MRM5r, (ops GR16:$dst, GR16:$src1, i16imm:$src2),
1975 "sub{w} {$src2, $dst|$dst, $src2}",
1976 [(set GR16:$dst, (sub GR16:$src1, imm:$src2))]>, OpSize;
1977def SUB32ri : Ii32<0x81, MRM5r, (ops GR32:$dst, GR32:$src1, i32imm:$src2),
1978 "sub{l} {$src2, $dst|$dst, $src2}",
1979 [(set GR32:$dst, (sub GR32:$src1, imm:$src2))]>;
1980def SUB16ri8 : Ii8<0x83, MRM5r, (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
1981 "sub{w} {$src2, $dst|$dst, $src2}",
1982 [(set GR16:$dst, (sub GR16:$src1, i16immSExt8:$src2))]>,
1983 OpSize;
1984def SUB32ri8 : Ii8<0x83, MRM5r, (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
1985 "sub{l} {$src2, $dst|$dst, $src2}",
1986 [(set GR32:$dst, (sub GR32:$src1, i32immSExt8:$src2))]>;
1987let isTwoAddress = 0 in {
1988 def SUB8mr : I<0x28, MRMDestMem, (ops i8mem :$dst, GR8 :$src2),
1989 "sub{b} {$src2, $dst|$dst, $src2}",
1990 [(store (sub (load addr:$dst), GR8:$src2), addr:$dst)]>;
1991 def SUB16mr : I<0x29, MRMDestMem, (ops i16mem:$dst, GR16:$src2),
1992 "sub{w} {$src2, $dst|$dst, $src2}",
1993 [(store (sub (load addr:$dst), GR16:$src2), addr:$dst)]>,
1994 OpSize;
1995 def SUB32mr : I<0x29, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
1996 "sub{l} {$src2, $dst|$dst, $src2}",
1997 [(store (sub (load addr:$dst), GR32:$src2), addr:$dst)]>;
1998 def SUB8mi : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2),
1999 "sub{b} {$src2, $dst|$dst, $src2}",
2000 [(store (sub (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
2001 def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2),
2002 "sub{w} {$src2, $dst|$dst, $src2}",
2003 [(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
2004 OpSize;
2005 def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2),
2006 "sub{l} {$src2, $dst|$dst, $src2}",
2007 [(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
2008 def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i16i8imm :$src2),
2009 "sub{w} {$src2, $dst|$dst, $src2}",
2010 [(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
2011 OpSize;
2012 def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i32i8imm :$src2),
2013 "sub{l} {$src2, $dst|$dst, $src2}",
2014 [(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
2015}
2016
2017def SBB32rr : I<0x19, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
2018 "sbb{l} {$src2, $dst|$dst, $src2}",
2019 [(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
2020
2021let isTwoAddress = 0 in {
2022 def SBB32mr : I<0x19, MRMDestMem, (ops i32mem:$dst, GR32:$src2),
2023 "sbb{l} {$src2, $dst|$dst, $src2}",
2024 [(store (sube (load addr:$dst), GR32:$src2), addr:$dst)]>;
2025 def SBB8mi : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2),
2026 "sbb{b} {$src2, $dst|$dst, $src2}",
2027 [(store (sube (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
2028 def SBB32mi : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2),
2029 "sbb{l} {$src2, $dst|$dst, $src2}",
2030 [(store (sube (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
2031 def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2),
2032 "sbb{l} {$src2, $dst|$dst, $src2}",
2033 [(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
2034}
2035def SBB32rm : I<0x1B, MRMSrcMem, (ops GR32:$dst, GR32:$src1, i32mem:$src2),
2036 "sbb{l} {$src2, $dst|$dst, $src2}",
2037 [(set GR32:$dst, (sube GR32:$src1, (load addr:$src2)))]>;
2038def SBB32ri : Ii32<0x81, MRM3r, (ops GR32:$dst, GR32:$src1, i32imm:$src2),
2039 "sbb{l} {$src2, $dst|$dst, $src2}",
2040 [(set GR32:$dst, (sube GR32:$src1, imm:$src2))]>;
2041def SBB32ri8 : Ii8<0x83, MRM3r, (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
2042 "sbb{l} {$src2, $dst|$dst, $src2}",
2043 [(set GR32:$dst, (sube GR32:$src1, i32immSExt8:$src2))]>;
2044
2045let isCommutable = 1 in { // X = IMUL Y, Z --> X = IMUL Z, Y
2046def IMUL16rr : I<0xAF, MRMSrcReg, (ops GR16:$dst, GR16:$src1, GR16:$src2),
2047 "imul{w} {$src2, $dst|$dst, $src2}",
2048 [(set GR16:$dst, (mul GR16:$src1, GR16:$src2))]>, TB, OpSize;
2049def IMUL32rr : I<0xAF, MRMSrcReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
2050 "imul{l} {$src2, $dst|$dst, $src2}",
2051 [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>, TB;
2052}
2053def IMUL16rm : I<0xAF, MRMSrcMem, (ops GR16:$dst, GR16:$src1, i16mem:$src2),
2054 "imul{w} {$src2, $dst|$dst, $src2}",
2055 [(set GR16:$dst, (mul GR16:$src1, (load addr:$src2)))]>,
2056 TB, OpSize;
2057def IMUL32rm : I<0xAF, MRMSrcMem, (ops GR32:$dst, GR32:$src1, i32mem:$src2),
2058 "imul{l} {$src2, $dst|$dst, $src2}",
2059 [(set GR32:$dst, (mul GR32:$src1, (load addr:$src2)))]>, TB;
2060
2061} // end Two Address instructions
2062
2063// Suprisingly enough, these are not two address instructions!
2064def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16
2065 (ops GR16:$dst, GR16:$src1, i16imm:$src2),
2066 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2067 [(set GR16:$dst, (mul GR16:$src1, imm:$src2))]>, OpSize;
2068def IMUL32rri : Ii32<0x69, MRMSrcReg, // GR32 = GR32*I32
2069 (ops GR32:$dst, GR32:$src1, i32imm:$src2),
2070 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2071 [(set GR32:$dst, (mul GR32:$src1, imm:$src2))]>;
2072def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // GR16 = GR16*I8
2073 (ops GR16:$dst, GR16:$src1, i16i8imm:$src2),
2074 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2075 [(set GR16:$dst, (mul GR16:$src1, i16immSExt8:$src2))]>,
2076 OpSize;
2077def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8
2078 (ops GR32:$dst, GR32:$src1, i32i8imm:$src2),
2079 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2080 [(set GR32:$dst, (mul GR32:$src1, i32immSExt8:$src2))]>;
2081
2082def IMUL16rmi : Ii16<0x69, MRMSrcMem, // GR16 = [mem16]*I16
2083 (ops GR16:$dst, i16mem:$src1, i16imm:$src2),
2084 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2085 [(set GR16:$dst, (mul (load addr:$src1), imm:$src2))]>,
2086 OpSize;
2087def IMUL32rmi : Ii32<0x69, MRMSrcMem, // GR32 = [mem32]*I32
2088 (ops GR32:$dst, i32mem:$src1, i32imm:$src2),
2089 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2090 [(set GR32:$dst, (mul (load addr:$src1), imm:$src2))]>;
2091def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // GR16 = [mem16]*I8
2092 (ops GR16:$dst, i16mem:$src1, i16i8imm :$src2),
2093 "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}",
2094 [(set GR16:$dst, (mul (load addr:$src1), i16immSExt8:$src2))]>,
2095 OpSize;
2096def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8
2097 (ops GR32:$dst, i32mem:$src1, i32i8imm: $src2),
2098 "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}",
2099 [(set GR32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
2100
2101//===----------------------------------------------------------------------===//
2102// Test instructions are just like AND, except they don't generate a result.
2103//
2104let isCommutable = 1 in { // TEST X, Y --> TEST Y, X
2105def TEST8rr : I<0x84, MRMDestReg, (ops GR8:$src1, GR8:$src2),
2106 "test{b} {$src2, $src1|$src1, $src2}",
2107 [(X86cmp (and GR8:$src1, GR8:$src2), 0)]>;
2108def TEST16rr : I<0x85, MRMDestReg, (ops GR16:$src1, GR16:$src2),
2109 "test{w} {$src2, $src1|$src1, $src2}",
2110 [(X86cmp (and GR16:$src1, GR16:$src2), 0)]>, OpSize;
2111def TEST32rr : I<0x85, MRMDestReg, (ops GR32:$src1, GR32:$src2),
2112 "test{l} {$src2, $src1|$src1, $src2}",
2113 [(X86cmp (and GR32:$src1, GR32:$src2), 0)]>;
2114}
2115
2116def TEST8rm : I<0x84, MRMSrcMem, (ops GR8 :$src1, i8mem :$src2),
2117 "test{b} {$src2, $src1|$src1, $src2}",
2118 [(X86cmp (and GR8:$src1, (loadi8 addr:$src2)), 0)]>;
2119def TEST16rm : I<0x85, MRMSrcMem, (ops GR16:$src1, i16mem:$src2),
2120 "test{w} {$src2, $src1|$src1, $src2}",
2121 [(X86cmp (and GR16:$src1, (loadi16 addr:$src2)), 0)]>,
2122 OpSize;
2123def TEST32rm : I<0x85, MRMSrcMem, (ops GR32:$src1, i32mem:$src2),
2124 "test{l} {$src2, $src1|$src1, $src2}",
2125 [(X86cmp (and GR32:$src1, (loadi32 addr:$src2)), 0)]>;
2126
2127def TEST8ri : Ii8 <0xF6, MRM0r, // flags = GR8 & imm8
2128 (ops GR8:$src1, i8imm:$src2),
2129 "test{b} {$src2, $src1|$src1, $src2}",
2130 [(X86cmp (and GR8:$src1, imm:$src2), 0)]>;
2131def TEST16ri : Ii16<0xF7, MRM0r, // flags = GR16 & imm16
2132 (ops GR16:$src1, i16imm:$src2),
2133 "test{w} {$src2, $src1|$src1, $src2}",
2134 [(X86cmp (and GR16:$src1, imm:$src2), 0)]>, OpSize;
2135def TEST32ri : Ii32<0xF7, MRM0r, // flags = GR32 & imm32
2136 (ops GR32:$src1, i32imm:$src2),
2137 "test{l} {$src2, $src1|$src1, $src2}",
2138 [(X86cmp (and GR32:$src1, imm:$src2), 0)]>;
2139
2140def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
2141 (ops i8mem:$src1, i8imm:$src2),
2142 "test{b} {$src2, $src1|$src1, $src2}",
2143 [(X86cmp (and (loadi8 addr:$src1), imm:$src2), 0)]>;
2144def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
2145 (ops i16mem:$src1, i16imm:$src2),
2146 "test{w} {$src2, $src1|$src1, $src2}",
2147 [(X86cmp (and (loadi16 addr:$src1), imm:$src2), 0)]>,
2148 OpSize;
2149def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
2150 (ops i32mem:$src1, i32imm:$src2),
2151 "test{l} {$src2, $src1|$src1, $src2}",
2152 [(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0)]>;
2153
2154
2155// Condition code ops, incl. set if equal/not equal/...
2156def SAHF : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>; // flags = AH
2157def LAHF : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>; // AH = flags
2158
2159def SETEr : I<0x94, MRM0r,
2160 (ops GR8 :$dst),
2161 "sete $dst",
2162 [(set GR8:$dst, (X86setcc X86_COND_E))]>,
2163 TB; // GR8 = ==
2164def SETEm : I<0x94, MRM0m,
2165 (ops i8mem:$dst),
2166 "sete $dst",
2167 [(store (X86setcc X86_COND_E), addr:$dst)]>,
2168 TB; // [mem8] = ==
2169def SETNEr : I<0x95, MRM0r,
2170 (ops GR8 :$dst),
2171 "setne $dst",
2172 [(set GR8:$dst, (X86setcc X86_COND_NE))]>,
2173 TB; // GR8 = !=
2174def SETNEm : I<0x95, MRM0m,
2175 (ops i8mem:$dst),
2176 "setne $dst",
2177 [(store (X86setcc X86_COND_NE), addr:$dst)]>,
2178 TB; // [mem8] = !=
2179def SETLr : I<0x9C, MRM0r,
2180 (ops GR8 :$dst),
2181 "setl $dst",
2182 [(set GR8:$dst, (X86setcc X86_COND_L))]>,
2183 TB; // GR8 = < signed
2184def SETLm : I<0x9C, MRM0m,
2185 (ops i8mem:$dst),
2186 "setl $dst",
2187 [(store (X86setcc X86_COND_L), addr:$dst)]>,
2188 TB; // [mem8] = < signed
2189def SETGEr : I<0x9D, MRM0r,
2190 (ops GR8 :$dst),
2191 "setge $dst",
2192 [(set GR8:$dst, (X86setcc X86_COND_GE))]>,
2193 TB; // GR8 = >= signed
2194def SETGEm : I<0x9D, MRM0m,
2195 (ops i8mem:$dst),
2196 "setge $dst",
2197 [(store (X86setcc X86_COND_GE), addr:$dst)]>,
2198 TB; // [mem8] = >= signed
2199def SETLEr : I<0x9E, MRM0r,
2200 (ops GR8 :$dst),
2201 "setle $dst",
2202 [(set GR8:$dst, (X86setcc X86_COND_LE))]>,
2203 TB; // GR8 = <= signed
2204def SETLEm : I<0x9E, MRM0m,
2205 (ops i8mem:$dst),
2206 "setle $dst",
2207 [(store (X86setcc X86_COND_LE), addr:$dst)]>,
2208 TB; // [mem8] = <= signed
2209def SETGr : I<0x9F, MRM0r,
2210 (ops GR8 :$dst),
2211 "setg $dst",
2212 [(set GR8:$dst, (X86setcc X86_COND_G))]>,
2213 TB; // GR8 = > signed
2214def SETGm : I<0x9F, MRM0m,
2215 (ops i8mem:$dst),
2216 "setg $dst",
2217 [(store (X86setcc X86_COND_G), addr:$dst)]>,
2218 TB; // [mem8] = > signed
2219
2220def SETBr : I<0x92, MRM0r,
2221 (ops GR8 :$dst),
2222 "setb $dst",
2223 [(set GR8:$dst, (X86setcc X86_COND_B))]>,
2224 TB; // GR8 = < unsign
2225def SETBm : I<0x92, MRM0m,
2226 (ops i8mem:$dst),
2227 "setb $dst",
2228 [(store (X86setcc X86_COND_B), addr:$dst)]>,
2229 TB; // [mem8] = < unsign
2230def SETAEr : I<0x93, MRM0r,
2231 (ops GR8 :$dst),
2232 "setae $dst",
2233 [(set GR8:$dst, (X86setcc X86_COND_AE))]>,
2234 TB; // GR8 = >= unsign
2235def SETAEm : I<0x93, MRM0m,
2236 (ops i8mem:$dst),
2237 "setae $dst",
2238 [(store (X86setcc X86_COND_AE), addr:$dst)]>,
2239 TB; // [mem8] = >= unsign
2240def SETBEr : I<0x96, MRM0r,
2241 (ops GR8 :$dst),
2242 "setbe $dst",
2243 [(set GR8:$dst, (X86setcc X86_COND_BE))]>,
2244 TB; // GR8 = <= unsign
2245def SETBEm : I<0x96, MRM0m,
2246 (ops i8mem:$dst),
2247 "setbe $dst",
2248 [(store (X86setcc X86_COND_BE), addr:$dst)]>,
2249 TB; // [mem8] = <= unsign
2250def SETAr : I<0x97, MRM0r,
2251 (ops GR8 :$dst),
2252 "seta $dst",
2253 [(set GR8:$dst, (X86setcc X86_COND_A))]>,
2254 TB; // GR8 = > signed
2255def SETAm : I<0x97, MRM0m,
2256 (ops i8mem:$dst),
2257 "seta $dst",
2258 [(store (X86setcc X86_COND_A), addr:$dst)]>,
2259 TB; // [mem8] = > signed
2260
2261def SETSr : I<0x98, MRM0r,
2262 (ops GR8 :$dst),
2263 "sets $dst",
2264 [(set GR8:$dst, (X86setcc X86_COND_S))]>,
2265 TB; // GR8 = <sign bit>
2266def SETSm : I<0x98, MRM0m,
2267 (ops i8mem:$dst),
2268 "sets $dst",
2269 [(store (X86setcc X86_COND_S), addr:$dst)]>,
2270 TB; // [mem8] = <sign bit>
2271def SETNSr : I<0x99, MRM0r,
2272 (ops GR8 :$dst),
2273 "setns $dst",
2274 [(set GR8:$dst, (X86setcc X86_COND_NS))]>,
2275 TB; // GR8 = !<sign bit>
2276def SETNSm : I<0x99, MRM0m,
2277 (ops i8mem:$dst),
2278 "setns $dst",
2279 [(store (X86setcc X86_COND_NS), addr:$dst)]>,
2280 TB; // [mem8] = !<sign bit>
2281def SETPr : I<0x9A, MRM0r,
2282 (ops GR8 :$dst),
2283 "setp $dst",
2284 [(set GR8:$dst, (X86setcc X86_COND_P))]>,
2285 TB; // GR8 = parity
2286def SETPm : I<0x9A, MRM0m,
2287 (ops i8mem:$dst),
2288 "setp $dst",
2289 [(store (X86setcc X86_COND_P), addr:$dst)]>,
2290 TB; // [mem8] = parity
2291def SETNPr : I<0x9B, MRM0r,
2292 (ops GR8 :$dst),
2293 "setnp $dst",
2294 [(set GR8:$dst, (X86setcc X86_COND_NP))]>,
2295 TB; // GR8 = not parity
2296def SETNPm : I<0x9B, MRM0m,
2297 (ops i8mem:$dst),
2298 "setnp $dst",
2299 [(store (X86setcc X86_COND_NP), addr:$dst)]>,
2300 TB; // [mem8] = not parity
2301
2302// Integer comparisons
2303def CMP8rr : I<0x38, MRMDestReg,
2304 (ops GR8 :$src1, GR8 :$src2),
2305 "cmp{b} {$src2, $src1|$src1, $src2}",
2306 [(X86cmp GR8:$src1, GR8:$src2)]>;
2307def CMP16rr : I<0x39, MRMDestReg,
2308 (ops GR16:$src1, GR16:$src2),
2309 "cmp{w} {$src2, $src1|$src1, $src2}",
2310 [(X86cmp GR16:$src1, GR16:$src2)]>, OpSize;
2311def CMP32rr : I<0x39, MRMDestReg,
2312 (ops GR32:$src1, GR32:$src2),
2313 "cmp{l} {$src2, $src1|$src1, $src2}",
2314 [(X86cmp GR32:$src1, GR32:$src2)]>;
2315def CMP8mr : I<0x38, MRMDestMem,
2316 (ops i8mem :$src1, GR8 :$src2),
2317 "cmp{b} {$src2, $src1|$src1, $src2}",
2318 [(X86cmp (loadi8 addr:$src1), GR8:$src2)]>;
2319def CMP16mr : I<0x39, MRMDestMem,
2320 (ops i16mem:$src1, GR16:$src2),
2321 "cmp{w} {$src2, $src1|$src1, $src2}",
2322 [(X86cmp (loadi16 addr:$src1), GR16:$src2)]>, OpSize;
2323def CMP32mr : I<0x39, MRMDestMem,
2324 (ops i32mem:$src1, GR32:$src2),
2325 "cmp{l} {$src2, $src1|$src1, $src2}",
2326 [(X86cmp (loadi32 addr:$src1), GR32:$src2)]>;
2327def CMP8rm : I<0x3A, MRMSrcMem,
2328 (ops GR8 :$src1, i8mem :$src2),
2329 "cmp{b} {$src2, $src1|$src1, $src2}",
2330 [(X86cmp GR8:$src1, (loadi8 addr:$src2))]>;
2331def CMP16rm : I<0x3B, MRMSrcMem,
2332 (ops GR16:$src1, i16mem:$src2),
2333 "cmp{w} {$src2, $src1|$src1, $src2}",
2334 [(X86cmp GR16:$src1, (loadi16 addr:$src2))]>, OpSize;
2335def CMP32rm : I<0x3B, MRMSrcMem,
2336 (ops GR32:$src1, i32mem:$src2),
2337 "cmp{l} {$src2, $src1|$src1, $src2}",
2338 [(X86cmp GR32:$src1, (loadi32 addr:$src2))]>;
2339def CMP8ri : Ii8<0x80, MRM7r,
2340 (ops GR8:$src1, i8imm:$src2),
2341 "cmp{b} {$src2, $src1|$src1, $src2}",
2342 [(X86cmp GR8:$src1, imm:$src2)]>;
2343def CMP16ri : Ii16<0x81, MRM7r,
2344 (ops GR16:$src1, i16imm:$src2),
2345 "cmp{w} {$src2, $src1|$src1, $src2}",
2346 [(X86cmp GR16:$src1, imm:$src2)]>, OpSize;
2347def CMP32ri : Ii32<0x81, MRM7r,
2348 (ops GR32:$src1, i32imm:$src2),
2349 "cmp{l} {$src2, $src1|$src1, $src2}",
2350 [(X86cmp GR32:$src1, imm:$src2)]>;
2351def CMP8mi : Ii8 <0x80, MRM7m,
2352 (ops i8mem :$src1, i8imm :$src2),
2353 "cmp{b} {$src2, $src1|$src1, $src2}",
2354 [(X86cmp (loadi8 addr:$src1), imm:$src2)]>;
2355def CMP16mi : Ii16<0x81, MRM7m,
2356 (ops i16mem:$src1, i16imm:$src2),
2357 "cmp{w} {$src2, $src1|$src1, $src2}",
2358 [(X86cmp (loadi16 addr:$src1), imm:$src2)]>, OpSize;
2359def CMP32mi : Ii32<0x81, MRM7m,
2360 (ops i32mem:$src1, i32imm:$src2),
2361 "cmp{l} {$src2, $src1|$src1, $src2}",
2362 [(X86cmp (loadi32 addr:$src1), imm:$src2)]>;
2363def CMP16ri8 : Ii8<0x83, MRM7r,
2364 (ops GR16:$src1, i16i8imm:$src2),
2365 "cmp{w} {$src2, $src1|$src1, $src2}",
2366 [(X86cmp GR16:$src1, i16immSExt8:$src2)]>, OpSize;
2367def CMP16mi8 : Ii8<0x83, MRM7m,
2368 (ops i16mem:$src1, i16i8imm:$src2),
2369 "cmp{w} {$src2, $src1|$src1, $src2}",
2370 [(X86cmp (loadi16 addr:$src1), i16immSExt8:$src2)]>, OpSize;
2371def CMP32mi8 : Ii8<0x83, MRM7m,
2372 (ops i32mem:$src1, i32i8imm:$src2),
2373 "cmp{l} {$src2, $src1|$src1, $src2}",
2374 [(X86cmp (loadi32 addr:$src1), i32immSExt8:$src2)]>;
2375def CMP32ri8 : Ii8<0x83, MRM7r,
2376 (ops GR32:$src1, i32i8imm:$src2),
2377 "cmp{l} {$src2, $src1|$src1, $src2}",
2378 [(X86cmp GR32:$src1, i32immSExt8:$src2)]>;
2379
2380// Sign/Zero extenders
2381def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops GR16:$dst, GR8 :$src),
2382 "movs{bw|x} {$src, $dst|$dst, $src}",
2383 [(set GR16:$dst, (sext GR8:$src))]>, TB, OpSize;
2384def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops GR16:$dst, i8mem :$src),
2385 "movs{bw|x} {$src, $dst|$dst, $src}",
2386 [(set GR16:$dst, (sextloadi16i8 addr:$src))]>, TB, OpSize;
2387def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops GR32:$dst, GR8 :$src),
2388 "movs{bl|x} {$src, $dst|$dst, $src}",
2389 [(set GR32:$dst, (sext GR8:$src))]>, TB;
2390def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops GR32:$dst, i8mem :$src),
2391 "movs{bl|x} {$src, $dst|$dst, $src}",
2392 [(set GR32:$dst, (sextloadi32i8 addr:$src))]>, TB;
2393def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops GR32:$dst, GR16:$src),
2394 "movs{wl|x} {$src, $dst|$dst, $src}",
2395 [(set GR32:$dst, (sext GR16:$src))]>, TB;
2396def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops GR32:$dst, i16mem:$src),
2397 "movs{wl|x} {$src, $dst|$dst, $src}",
2398 [(set GR32:$dst, (sextloadi32i16 addr:$src))]>, TB;
2399
2400def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops GR16:$dst, GR8 :$src),
2401 "movz{bw|x} {$src, $dst|$dst, $src}",
2402 [(set GR16:$dst, (zext GR8:$src))]>, TB, OpSize;
2403def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops GR16:$dst, i8mem :$src),
2404 "movz{bw|x} {$src, $dst|$dst, $src}",
2405 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>, TB, OpSize;
2406def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops GR32:$dst, GR8 :$src),
2407 "movz{bl|x} {$src, $dst|$dst, $src}",
2408 [(set GR32:$dst, (zext GR8:$src))]>, TB;
2409def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops GR32:$dst, i8mem :$src),
2410 "movz{bl|x} {$src, $dst|$dst, $src}",
2411 [(set GR32:$dst, (zextloadi32i8 addr:$src))]>, TB;
2412def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops GR32:$dst, GR16:$src),
2413 "movz{wl|x} {$src, $dst|$dst, $src}",
2414 [(set GR32:$dst, (zext GR16:$src))]>, TB;
2415def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops GR32:$dst, i16mem:$src),
2416 "movz{wl|x} {$src, $dst|$dst, $src}",
2417 [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
2418
2419def CBW : I<0x98, RawFrm, (ops),
2420 "{cbtw|cbw}", []>, Imp<[AL],[AX]>, OpSize; // AX = signext(AL)
2421def CWDE : I<0x98, RawFrm, (ops),
2422 "{cwtl|cwde}", []>, Imp<[AX],[EAX]>; // EAX = signext(AX)
2423
2424def CWD : I<0x99, RawFrm, (ops),
2425 "{cwtd|cwd}", []>, Imp<[AX],[AX,DX]>, OpSize; // DX:AX = signext(AX)
2426def CDQ : I<0x99, RawFrm, (ops),
2427 "{cltd|cdq}", []>, Imp<[EAX],[EAX,EDX]>; // EDX:EAX = signext(EAX)
2428
2429
2430//===----------------------------------------------------------------------===//
2431// Alias Instructions
2432//===----------------------------------------------------------------------===//
2433
2434// Alias instructions that map movr0 to xor.
2435// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
2436def MOV8r0 : I<0x30, MRMInitReg, (ops GR8 :$dst),
2437 "xor{b} $dst, $dst",
2438 [(set GR8:$dst, 0)]>;
2439def MOV16r0 : I<0x31, MRMInitReg, (ops GR16:$dst),
2440 "xor{w} $dst, $dst",
2441 [(set GR16:$dst, 0)]>, OpSize;
2442def MOV32r0 : I<0x31, MRMInitReg, (ops GR32:$dst),
2443 "xor{l} $dst, $dst",
2444 [(set GR32:$dst, 0)]>;
2445
2446// Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only
2447// those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX).
2448def MOV16to16_ : I<0x89, MRMDestReg, (ops GR16_:$dst, GR16:$src),
2449 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
2450def MOV32to32_ : I<0x89, MRMDestReg, (ops GR32_:$dst, GR32:$src),
2451 "mov{l} {$src, $dst|$dst, $src}", []>;
2452
2453def MOV16_rr : I<0x89, MRMDestReg, (ops GR16_:$dst, GR16_:$src),
2454 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
2455def MOV32_rr : I<0x89, MRMDestReg, (ops GR32_:$dst, GR32_:$src),
2456 "mov{l} {$src, $dst|$dst, $src}", []>;
2457def MOV16_rm : I<0x8B, MRMSrcMem, (ops GR16_:$dst, i16mem:$src),
2458 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
2459def MOV32_rm : I<0x8B, MRMSrcMem, (ops GR32_:$dst, i32mem:$src),
2460 "mov{l} {$src, $dst|$dst, $src}", []>;
2461def MOV16_mr : I<0x89, MRMDestMem, (ops i16mem:$dst, GR16_:$src),
2462 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
2463def MOV32_mr : I<0x89, MRMDestMem, (ops i32mem:$dst, GR32_:$src),
2464 "mov{l} {$src, $dst|$dst, $src}", []>;
2465
2466//===----------------------------------------------------------------------===//
2467// Thread Local Storage Instructions
2468//
2469
2470def TLS_addr : I<0, Pseudo, (ops GR32:$dst, i32imm:$sym),
2471 "leal ${sym:mem}(,%ebx,1), $dst",
2472 [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>,
2473 Imp<[EBX],[]>;
2474
2475let AddedComplexity = 10 in
2476def TLS_gs_rr : I<0, Pseudo, (ops GR32:$dst, GR32:$src),
2477 "movl %gs:($src), $dst",
2478 [(set GR32:$dst, (load (add X86TLStp, GR32:$src)))]>;
2479
2480let AddedComplexity = 15 in
2481def TLS_gs_ri : I<0, Pseudo, (ops GR32:$dst, i32imm:$src),
2482 "movl %gs:${src:mem}, $dst",
2483 [(set GR32:$dst,
2484 (load (add X86TLStp, (X86Wrapper tglobaltlsaddr:$src))))]>;
2485
2486def TLS_tp : I<0, Pseudo, (ops GR32:$dst),
2487 "movl %gs:0, $dst",
2488 [(set GR32:$dst, X86TLStp)]>;
2489
2490//===----------------------------------------------------------------------===//
2491// DWARF Pseudo Instructions
2492//
2493
2494def DWARF_LOC : I<0, Pseudo, (ops i32imm:$line, i32imm:$col, i32imm:$file),
2495 "; .loc $file, $line, $col",
2496 [(dwarf_loc (i32 imm:$line), (i32 imm:$col),
2497 (i32 imm:$file))]>;
2498
2499//===----------------------------------------------------------------------===//
2500// EH Pseudo Instructions
2501//
2502let isTerminator = 1, isReturn = 1, isBarrier = 1,
2503 hasCtrlDep = 1, noResults = 1 in {
2504def EH_RETURN : I<0xC3, RawFrm, (ops GR32:$addr),
2505 "ret #eh_return, addr: $addr",
2506 [(X86ehret GR32:$addr)]>;
2507
2508}
2509
2510//===----------------------------------------------------------------------===//
2511// Non-Instruction Patterns
2512//===----------------------------------------------------------------------===//
2513
2514// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
2515def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>;
2516def : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>;
2517def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)), (MOV32ri tglobaltlsaddr:$dst)>;
2518def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>;
2519def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>;
2520
2521def : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)),
2522 (ADD32ri GR32:$src1, tconstpool:$src2)>;
2523def : Pat<(add GR32:$src1, (X86Wrapper tjumptable:$src2)),
2524 (ADD32ri GR32:$src1, tjumptable:$src2)>;
2525def : Pat<(add GR32:$src1, (X86Wrapper tglobaladdr :$src2)),
2526 (ADD32ri GR32:$src1, tglobaladdr:$src2)>;
2527def : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)),
2528 (ADD32ri GR32:$src1, texternalsym:$src2)>;
2529
2530def : Pat<(store (i32 (X86Wrapper tglobaladdr:$src)), addr:$dst),
2531 (MOV32mi addr:$dst, tglobaladdr:$src)>;
2532def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst),
2533 (MOV32mi addr:$dst, texternalsym:$src)>;
2534
2535// Calls
2536def : Pat<(X86tailcall GR32:$dst),
2537 (CALL32r GR32:$dst)>;
2538
2539def : Pat<(X86tailcall (i32 tglobaladdr:$dst)),
2540 (CALLpcrel32 tglobaladdr:$dst)>;
2541def : Pat<(X86tailcall (i32 texternalsym:$dst)),
2542 (CALLpcrel32 texternalsym:$dst)>;
2543
2544def : Pat<(X86call (i32 tglobaladdr:$dst)),
2545 (CALLpcrel32 tglobaladdr:$dst)>;
2546def : Pat<(X86call (i32 texternalsym:$dst)),
2547 (CALLpcrel32 texternalsym:$dst)>;
2548
2549// X86 specific add which produces a flag.
2550def : Pat<(addc GR32:$src1, GR32:$src2),
2551 (ADD32rr GR32:$src1, GR32:$src2)>;
2552def : Pat<(addc GR32:$src1, (load addr:$src2)),
2553 (ADD32rm GR32:$src1, addr:$src2)>;
2554def : Pat<(addc GR32:$src1, imm:$src2),
2555 (ADD32ri GR32:$src1, imm:$src2)>;
2556def : Pat<(addc GR32:$src1, i32immSExt8:$src2),
2557 (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
2558
2559def : Pat<(subc GR32:$src1, GR32:$src2),
2560 (SUB32rr GR32:$src1, GR32:$src2)>;
2561def : Pat<(subc GR32:$src1, (load addr:$src2)),
2562 (SUB32rm GR32:$src1, addr:$src2)>;
2563def : Pat<(subc GR32:$src1, imm:$src2),
2564 (SUB32ri GR32:$src1, imm:$src2)>;
2565def : Pat<(subc GR32:$src1, i32immSExt8:$src2),
2566 (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;
2567
2568def : Pat<(truncstorei1 (i8 imm:$src), addr:$dst),
2569 (MOV8mi addr:$dst, imm:$src)>;
2570def : Pat<(truncstorei1 GR8:$src, addr:$dst),
2571 (MOV8mr addr:$dst, GR8:$src)>;
2572
2573// Comparisons.
2574
2575// TEST R,R is smaller than CMP R,0
2576def : Pat<(X86cmp GR8:$src1, 0),
2577 (TEST8rr GR8:$src1, GR8:$src1)>;
2578def : Pat<(X86cmp GR16:$src1, 0),
2579 (TEST16rr GR16:$src1, GR16:$src1)>;
2580def : Pat<(X86cmp GR32:$src1, 0),
2581 (TEST32rr GR32:$src1, GR32:$src1)>;
2582
2583// {s|z}extload bool -> {s|z}extload byte
2584def : Pat<(sextloadi16i1 addr:$src), (MOVSX16rm8 addr:$src)>;
2585def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>;
2586def : Pat<(zextloadi8i1 addr:$src), (MOV8rm addr:$src)>;
2587def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
2588def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
2589
2590// extload bool -> extload byte
2591def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
2592def : Pat<(extloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
2593def : Pat<(extloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
2594def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
2595def : Pat<(extloadi32i8 addr:$src), (MOVZX32rm8 addr:$src)>;
2596def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
2597
2598// anyext -> zext
2599def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8 GR8 :$src)>;
2600def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>;
2601def : Pat<(i32 (anyext GR16:$src)), (MOVZX32rr16 GR16:$src)>;
2602def : Pat<(i16 (anyext (loadi8 addr:$src))), (MOVZX16rm8 addr:$src)>;
2603def : Pat<(i32 (anyext (loadi8 addr:$src))), (MOVZX32rm8 addr:$src)>;
2604def : Pat<(i32 (anyext (loadi16 addr:$src))), (MOVZX32rm16 addr:$src)>;
2605
2606//===----------------------------------------------------------------------===//
2607// Some peepholes
2608//===----------------------------------------------------------------------===//
2609
2610// (shl x, 1) ==> (add x, x)
2611def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>;
2612def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>;
2613def : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>;
2614
2615// (or (x >> c) | (y << (32 - c))) ==> (shrd32 x, y, c)
2616def : Pat<(or (srl GR32:$src1, CL:$amt),
2617 (shl GR32:$src2, (sub 32, CL:$amt))),
2618 (SHRD32rrCL GR32:$src1, GR32:$src2)>;
2619
2620def : Pat<(store (or (srl (loadi32 addr:$dst), CL:$amt),
2621 (shl GR32:$src2, (sub 32, CL:$amt))), addr:$dst),
2622 (SHRD32mrCL addr:$dst, GR32:$src2)>;
2623
2624// (or (x << c) | (y >> (32 - c))) ==> (shld32 x, y, c)
2625def : Pat<(or (shl GR32:$src1, CL:$amt),
2626 (srl GR32:$src2, (sub 32, CL:$amt))),
2627 (SHLD32rrCL GR32:$src1, GR32:$src2)>;
2628
2629def : Pat<(store (or (shl (loadi32 addr:$dst), CL:$amt),
2630 (srl GR32:$src2, (sub 32, CL:$amt))), addr:$dst),
2631 (SHLD32mrCL addr:$dst, GR32:$src2)>;
2632
2633// (or (x >> c) | (y << (16 - c))) ==> (shrd16 x, y, c)
2634def : Pat<(or (srl GR16:$src1, CL:$amt),
2635 (shl GR16:$src2, (sub 16, CL:$amt))),
2636 (SHRD16rrCL GR16:$src1, GR16:$src2)>;
2637
2638def : Pat<(store (or (srl (loadi16 addr:$dst), CL:$amt),
2639 (shl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
2640 (SHRD16mrCL addr:$dst, GR16:$src2)>;
2641
2642// (or (x << c) | (y >> (16 - c))) ==> (shld16 x, y, c)
2643def : Pat<(or (shl GR16:$src1, CL:$amt),
2644 (srl GR16:$src2, (sub 16, CL:$amt))),
2645 (SHLD16rrCL GR16:$src1, GR16:$src2)>;
2646
2647def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt),
2648 (srl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
2649 (SHLD16mrCL addr:$dst, GR16:$src2)>;
2650
2651
2652//===----------------------------------------------------------------------===//
2653// Floating Point Stack Support
2654//===----------------------------------------------------------------------===//
2655
2656include "X86InstrFPStack.td"
2657
2658//===----------------------------------------------------------------------===//
2659// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2)
2660//===----------------------------------------------------------------------===//
2661
2662include "X86InstrMMX.td"
2663
2664//===----------------------------------------------------------------------===//
2665// XMM Floating point support (requires SSE / SSE2)
2666//===----------------------------------------------------------------------===//
2667
2668include "X86InstrSSE.td"
2669
2670//===----------------------------------------------------------------------===//
2671// X86-64 Support
2672//===----------------------------------------------------------------------===//
2673
2674include "X86InstrX86-64.td"