blob: c4b25fca2fc9ed2953a9a69ec1a76de7f1110b7a [file] [log] [blame]
Chris Lattner36fe6d22008-01-10 05:50:42 +00001//====- X86Instr64bit.td - Describe X86-64 Instructions ----*- tablegen -*-===//
Evan Cheng25ab6902006-09-08 06:48:29 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Evan Cheng25ab6902006-09-08 06:48:29 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the X86-64 instruction set, defining the instructions,
11// and properties of the instructions which are needed for code generation,
12// machine code emission, and analysis.
13//
14//===----------------------------------------------------------------------===//
15
16//===----------------------------------------------------------------------===//
Chris Lattner36fe6d22008-01-10 05:50:42 +000017// Operand Definitions.
Evan Cheng25ab6902006-09-08 06:48:29 +000018//
19
20// 64-bits but only 32 bits are significant.
21def i64i32imm : Operand<i64>;
Chris Lattner7680e732009-06-20 19:34:09 +000022
23// 64-bits but only 32 bits are significant, and those bits are treated as being
24// pc relative.
25def i64i32imm_pcrel : Operand<i64> {
26 let PrintMethod = "print_pcrel_imm";
27}
28
29
Evan Cheng25ab6902006-09-08 06:48:29 +000030// 64-bits but only 8 bits are significant.
31def i64i8imm : Operand<i64>;
32
33def lea64mem : Operand<i64> {
Rafael Espindola094fad32009-04-08 21:14:34 +000034 let PrintMethod = "printlea64mem";
Evan Cheng25ab6902006-09-08 06:48:29 +000035 let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm);
36}
37
38def lea64_32mem : Operand<i32> {
39 let PrintMethod = "printlea64_32mem";
Chris Lattnerc1243062009-06-20 07:03:18 +000040 let AsmOperandLowerMethod = "lower_lea64_32mem";
Evan Cheng25ab6902006-09-08 06:48:29 +000041 let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
42}
43
44//===----------------------------------------------------------------------===//
Chris Lattner36fe6d22008-01-10 05:50:42 +000045// Complex Pattern Definitions.
Evan Cheng25ab6902006-09-08 06:48:29 +000046//
47def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
Chris Lattner65a7a6f2009-07-11 23:17:29 +000048 [add, mul, X86mul_imm, shl, or, frameindex,
49 X86WrapperRIP], []>;
Evan Cheng25ab6902006-09-08 06:48:29 +000050
Chris Lattner5c0b16d2009-06-20 20:38:48 +000051def tls64addr : ComplexPattern<i64, 4, "SelectTLSADDRAddr",
52 [tglobaltlsaddr], []>;
53
Evan Cheng25ab6902006-09-08 06:48:29 +000054//===----------------------------------------------------------------------===//
Chris Lattner36fe6d22008-01-10 05:50:42 +000055// Pattern fragments.
Evan Cheng25ab6902006-09-08 06:48:29 +000056//
57
Dan Gohman018a34c2008-12-19 18:25:21 +000058def i64immSExt8 : PatLeaf<(i64 imm), [{
59 // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit
60 // sign extended field.
61 return (int64_t)N->getZExtValue() == (int8_t)N->getZExtValue();
62}]>;
63
Evan Cheng25ab6902006-09-08 06:48:29 +000064def i64immSExt32 : PatLeaf<(i64 imm), [{
65 // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
66 // sign extended field.
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +000067 return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
Evan Cheng25ab6902006-09-08 06:48:29 +000068}]>;
69
70def i64immZExt32 : PatLeaf<(i64 imm), [{
71 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
72 // unsignedsign extended field.
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +000073 return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
Evan Cheng25ab6902006-09-08 06:48:29 +000074}]>;
75
Evan Cheng466685d2006-10-09 20:57:25 +000076def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
77def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
78def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
Evan Cheng25ab6902006-09-08 06:48:29 +000079
Evan Cheng466685d2006-10-09 20:57:25 +000080def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
81def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
82def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
83def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
Evan Cheng25ab6902006-09-08 06:48:29 +000084
Evan Cheng466685d2006-10-09 20:57:25 +000085def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
86def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
87def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
88def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
Evan Cheng25ab6902006-09-08 06:48:29 +000089
90//===----------------------------------------------------------------------===//
91// Instruction list...
92//
93
Dan Gohman6d4b0522008-10-01 18:28:06 +000094// ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into
95// a stack adjustment and the codegen must know that they may modify the stack
96// pointer before prolog-epilog rewriting occurs.
97// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
98// sub / add which can clobber EFLAGS.
99let Defs = [RSP, EFLAGS], Uses = [RSP] in {
100def ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs), (ins i32imm:$amt),
101 "#ADJCALLSTACKDOWN",
Chris Lattnere563bbc2008-10-11 22:08:30 +0000102 [(X86callseq_start timm:$amt)]>,
Dan Gohman6d4b0522008-10-01 18:28:06 +0000103 Requires<[In64BitMode]>;
104def ADJCALLSTACKUP64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
105 "#ADJCALLSTACKUP",
Chris Lattnere563bbc2008-10-11 22:08:30 +0000106 [(X86callseq_end timm:$amt1, timm:$amt2)]>,
Dan Gohman6d4b0522008-10-01 18:28:06 +0000107 Requires<[In64BitMode]>;
108}
109
Evan Cheng25ab6902006-09-08 06:48:29 +0000110//===----------------------------------------------------------------------===//
111// Call Instructions...
112//
Evan Chengffbacca2007-07-21 00:34:19 +0000113let isCall = 1 in
Dan Gohman6d4b0522008-10-01 18:28:06 +0000114 // All calls clobber the non-callee saved registers. RSP is marked as
115 // a use to prevent stack-pointer assignments that appear immediately
116 // before calls from potentially appearing dead. Uses for argument
117 // registers are added manually.
Evan Cheng25ab6902006-09-08 06:48:29 +0000118 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
Evan Cheng0d9e9762008-01-29 19:34:22 +0000119 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
Bill Wendlingbff35d12007-04-26 21:06:48 +0000120 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
Evan Cheng25ab6902006-09-08 06:48:29 +0000121 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
Dan Gohman2662d552008-10-01 04:14:30 +0000122 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
123 Uses = [RSP] in {
Chris Lattnerff81ebf2009-03-18 00:43:52 +0000124
125 // NOTE: this pattern doesn't match "X86call imm", because we do not know
126 // that the offset between an arbitrary immediate and the call will fit in
127 // the 32-bit pcrel field that we have.
Evan Cheng876eac92009-06-16 19:44:27 +0000128 def CALL64pcrel32 : Ii32<0xE8, RawFrm,
Chris Lattner7680e732009-06-20 19:34:09 +0000129 (outs), (ins i64i32imm_pcrel:$dst, variable_ops),
130 "call\t$dst", []>,
Evan Chenga0652002009-03-12 18:15:39 +0000131 Requires<[In64BitMode]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000132 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000133 "call\t{*}$dst", [(X86call GR64:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000134 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
Dan Gohmanb4106172008-05-29 21:50:34 +0000135 "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000136 }
137
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000138
139
140let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Cheng7403eea2009-02-10 21:39:44 +0000141def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset,
142 variable_ops),
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000143 "#TC_RETURN $dst $offset",
144 []>;
145
146let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Cheng7403eea2009-02-10 21:39:44 +0000147def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
148 variable_ops),
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000149 "#TC_RETURN $dst $offset",
150 []>;
151
152
153let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Cheng7403eea2009-02-10 21:39:44 +0000154 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst),
155 "jmp{q}\t{*}$dst # TAILCALL",
156 []>;
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000157
Evan Cheng25ab6902006-09-08 06:48:29 +0000158// Branches
Owen Anderson20ab2902007-11-12 07:39:39 +0000159let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
Dan Gohmanb1576f52007-07-31 20:11:57 +0000160 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000161 [(brind GR64:$dst)]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000162 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000163 [(brind (loadi64 addr:$dst))]>;
164}
165
166//===----------------------------------------------------------------------===//
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000167// EH Pseudo Instructions
168//
169let isTerminator = 1, isReturn = 1, isBarrier = 1,
170 hasCtrlDep = 1 in {
171def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
172 "ret\t#eh_return, addr: $addr",
173 [(X86ehret GR64:$addr)]>;
174
175}
176
177//===----------------------------------------------------------------------===//
Evan Cheng25ab6902006-09-08 06:48:29 +0000178// Miscellaneous Instructions...
179//
Chris Lattnerba7e7562008-01-10 07:59:24 +0000180let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
Evan Cheng25ab6902006-09-08 06:48:29 +0000181def LEAVE64 : I<0xC9, RawFrm,
Evan Cheng071a2792007-09-11 19:55:27 +0000182 (outs), (ins), "leave", []>;
Chris Lattnerba7e7562008-01-10 07:59:24 +0000183let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
184let mayLoad = 1 in
Evan Cheng25ab6902006-09-08 06:48:29 +0000185def POP64r : I<0x58, AddRegFrm,
Evan Cheng071a2792007-09-11 19:55:27 +0000186 (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
Chris Lattnerba7e7562008-01-10 07:59:24 +0000187let mayStore = 1 in
Dan Gohman638c96d2007-06-18 14:12:56 +0000188def PUSH64r : I<0x50, AddRegFrm,
Evan Cheng071a2792007-09-11 19:55:27 +0000189 (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
190}
Evan Cheng25ab6902006-09-08 06:48:29 +0000191
Bill Wendling453eb262009-06-15 19:39:04 +0000192let Defs = [RSP], Uses = [RSP], neverHasSideEffects = 1, mayStore = 1 in {
193def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i8imm:$imm),
Bill Wendling927788c2009-06-15 20:59:31 +0000194 "push{q}\t$imm", []>;
Bill Wendling453eb262009-06-15 19:39:04 +0000195def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
Bill Wendling927788c2009-06-15 20:59:31 +0000196 "push{q}\t$imm", []>;
Bill Wendling453eb262009-06-15 19:39:04 +0000197def PUSH64i32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
Bill Wendling927788c2009-06-15 20:59:31 +0000198 "push{q}\t$imm", []>;
Bill Wendling453eb262009-06-15 19:39:04 +0000199}
200
Chris Lattnerba7e7562008-01-10 07:59:24 +0000201let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
Evan Chengbf4f89d2007-09-26 21:28:00 +0000202def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
Chris Lattnerba7e7562008-01-10 07:59:24 +0000203let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
Evan Chengbf4f89d2007-09-26 21:28:00 +0000204def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
Evan Cheng2f245ba2007-09-26 01:29:06 +0000205
Evan Cheng25ab6902006-09-08 06:48:29 +0000206def LEA64_32r : I<0x8D, MRMSrcMem,
Evan Cheng64d80e32007-07-19 01:14:50 +0000207 (outs GR32:$dst), (ins lea64_32mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000208 "lea{l}\t{$src|$dst}, {$dst|$src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000209 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
210
Evan Chenge771ebd2008-03-27 01:41:09 +0000211let isReMaterializable = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000212def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000213 "lea{q}\t{$src|$dst}, {$dst|$src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000214 [(set GR64:$dst, lea64addr:$src)]>;
215
216let isTwoAddress = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000217def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000218 "bswap{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000219 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +0000220
Evan Cheng18efe262007-12-14 02:13:44 +0000221// Bit scan instructions.
222let Defs = [EFLAGS] in {
Evan Chengfd9e4732007-12-14 18:49:43 +0000223def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman1a8001e2007-12-14 15:10:00 +0000224 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng8ec86112007-12-14 18:25:34 +0000225 [(set GR64:$dst, (X86bsf GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng18efe262007-12-14 02:13:44 +0000226def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohman1a8001e2007-12-14 15:10:00 +0000227 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng8ec86112007-12-14 18:25:34 +0000228 [(set GR64:$dst, (X86bsf (loadi64 addr:$src))),
229 (implicit EFLAGS)]>, TB;
Evan Cheng18efe262007-12-14 02:13:44 +0000230
Evan Chengfd9e4732007-12-14 18:49:43 +0000231def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman1a8001e2007-12-14 15:10:00 +0000232 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng8ec86112007-12-14 18:25:34 +0000233 [(set GR64:$dst, (X86bsr GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng18efe262007-12-14 02:13:44 +0000234def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohman1a8001e2007-12-14 15:10:00 +0000235 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng8ec86112007-12-14 18:25:34 +0000236 [(set GR64:$dst, (X86bsr (loadi64 addr:$src))),
237 (implicit EFLAGS)]>, TB;
Evan Cheng18efe262007-12-14 02:13:44 +0000238} // Defs = [EFLAGS]
239
Evan Cheng25ab6902006-09-08 06:48:29 +0000240// Repeat string ops
Evan Cheng071a2792007-09-11 19:55:27 +0000241let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000242def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
Evan Cheng071a2792007-09-11 19:55:27 +0000243 [(X86rep_movs i64)]>, REP;
244let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000245def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
Evan Cheng071a2792007-09-11 19:55:27 +0000246 [(X86rep_stos i64)]>, REP;
Evan Cheng25ab6902006-09-08 06:48:29 +0000247
248//===----------------------------------------------------------------------===//
249// Move Instructions...
250//
251
Chris Lattnerba7e7562008-01-10 07:59:24 +0000252let neverHasSideEffects = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000253def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000254 "mov{q}\t{$src, $dst|$dst, $src}", []>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000255
Evan Cheng601ca4b2008-06-25 01:16:38 +0000256let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Evan Cheng64d80e32007-07-19 01:14:50 +0000257def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000258 "movabs{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000259 [(set GR64:$dst, imm:$src)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000260def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000261 "mov{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000262 [(set GR64:$dst, i64immSExt32:$src)]>;
Dan Gohman1ab79892007-09-07 21:32:51 +0000263}
Evan Cheng25ab6902006-09-08 06:48:29 +0000264
Dan Gohman15511cf2008-12-03 18:15:48 +0000265let canFoldAsLoad = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000266def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000267 "mov{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000268 [(set GR64:$dst, (load addr:$src))]>;
269
Evan Cheng64d80e32007-07-19 01:14:50 +0000270def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000271 "mov{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000272 [(store GR64:$src, addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000273def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000274 "mov{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000275 [(store i64immSExt32:$src, addr:$dst)]>;
276
277// Sign/Zero extenders
278
Dan Gohman04d19f02009-04-13 15:13:28 +0000279// MOVSX64rr8 always has a REX prefix and it has an 8-bit register
280// operand, which makes it a rare instruction with an 8-bit register
281// operand that can never access an h register. If support for h registers
282// were generalized, this would require a special register class.
Evan Cheng64d80e32007-07-19 01:14:50 +0000283def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000284 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000285 [(set GR64:$dst, (sext GR8:$src))]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000286def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000287 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000288 [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000289def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000290 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000291 [(set GR64:$dst, (sext GR16:$src))]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000292def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000293 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000294 [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000295def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000296 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000297 [(set GR64:$dst, (sext GR32:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000298def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000299 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000300 [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
301
Dan Gohman11ba3b12008-07-30 18:09:17 +0000302// Use movzbl instead of movzbq when the destination is a register; it's
303// equivalent due to implicit zero-extending, and it has a smaller encoding.
304def MOVZX64rr8 : I<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
305 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
306 [(set GR64:$dst, (zext GR8:$src))]>, TB;
307def MOVZX64rm8 : I<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
308 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
309 [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
310// Use movzwl instead of movzwq when the destination is a register; it's
311// equivalent due to implicit zero-extending, and it has a smaller encoding.
312def MOVZX64rr16: I<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
313 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
314 [(set GR64:$dst, (zext GR16:$src))]>, TB;
315def MOVZX64rm16: I<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
316 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
317 [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +0000318
Dan Gohmane3d92062008-08-07 02:54:50 +0000319// There's no movzlq instruction, but movl can be used for this purpose, using
Dan Gohman97121ba2009-04-08 00:15:30 +0000320// implicit zero-extension. The preferred way to do 32-bit-to-64-bit zero
321// extension on x86-64 is to use a SUBREG_TO_REG to utilize implicit
322// zero-extension, however this isn't possible when the 32-bit value is
323// defined by a truncate or is copied from something where the high bits aren't
324// necessarily all zero. In such cases, we fall back to these explicit zext
325// instructions.
Dan Gohmane3d92062008-08-07 02:54:50 +0000326def MOVZX64rr32 : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
327 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
328 [(set GR64:$dst, (zext GR32:$src))]>;
329def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
330 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
331 [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
332
Dan Gohman97121ba2009-04-08 00:15:30 +0000333// Any instruction that defines a 32-bit result leaves the high half of the
334// register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
335// be copying from a truncate, but any other 32-bit operation will zero-extend
336// up to 64 bits.
337def def32 : PatLeaf<(i32 GR32:$src), [{
338 return N->getOpcode() != ISD::TRUNCATE &&
339 N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
340 N->getOpcode() != ISD::CopyFromReg;
341}]>;
342
343// In the case of a 32-bit def that is known to implicitly zero-extend,
344// we can use a SUBREG_TO_REG.
345def : Pat<(i64 (zext def32:$src)),
346 (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
347
Chris Lattnerba7e7562008-01-10 07:59:24 +0000348let neverHasSideEffects = 1 in {
349 let Defs = [RAX], Uses = [EAX] in
350 def CDQE : RI<0x98, RawFrm, (outs), (ins),
351 "{cltq|cdqe}", []>; // RAX = signext(EAX)
Evan Cheng25ab6902006-09-08 06:48:29 +0000352
Chris Lattnerba7e7562008-01-10 07:59:24 +0000353 let Defs = [RAX,RDX], Uses = [RAX] in
354 def CQO : RI<0x99, RawFrm, (outs), (ins),
355 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
356}
Evan Cheng25ab6902006-09-08 06:48:29 +0000357
358//===----------------------------------------------------------------------===//
359// Arithmetic Instructions...
360//
361
Evan Cheng24f2ea32007-09-14 21:48:26 +0000362let Defs = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000363let isTwoAddress = 1 in {
364let isConvertibleToThreeAddress = 1 in {
365let isCommutable = 1 in
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000366// Register-Register Addition
367def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
368 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000369 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000370 (implicit EFLAGS)]>;
371
372// Register-Integer Addition
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000373def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
374 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000375 [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)),
376 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000377def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
378 "add{q}\t{$src2, $dst|$dst, $src2}",
379 [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)),
380 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000381} // isConvertibleToThreeAddress
382
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000383// Register-Memory Addition
384def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
385 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000386 [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))),
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000387 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000388} // isTwoAddress
389
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000390// Memory-Register Addition
Evan Cheng64d80e32007-07-19 01:14:50 +0000391def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000392 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000393 [(store (add (load addr:$dst), GR64:$src2), addr:$dst),
394 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000395def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000396 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000397 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst),
398 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000399def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
400 "add{q}\t{$src2, $dst|$dst, $src2}",
401 [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst),
402 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000403
Evan Cheng3154cb62007-10-05 17:59:57 +0000404let Uses = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000405let isTwoAddress = 1 in {
406let isCommutable = 1 in
Dale Johannesen874ae252009-06-02 03:12:52 +0000407def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000408 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000409 [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000410
Dale Johannesen874ae252009-06-02 03:12:52 +0000411def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000412 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000413 [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000414
Dale Johannesen874ae252009-06-02 03:12:52 +0000415def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000416 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000417 [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
418def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +0000419 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000420 [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000421} // isTwoAddress
422
Evan Cheng64d80e32007-07-19 01:14:50 +0000423def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000424 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000425 [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000426def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000427 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000428 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000429def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
430 "adc{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000431 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Evan Cheng3154cb62007-10-05 17:59:57 +0000432} // Uses = [EFLAGS]
Evan Cheng25ab6902006-09-08 06:48:29 +0000433
434let isTwoAddress = 1 in {
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000435// Register-Register Subtraction
Evan Cheng64d80e32007-07-19 01:14:50 +0000436def SUB64rr : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000437 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000438 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2)),
439 (implicit EFLAGS)]>;
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000440
441// Register-Memory Subtraction
Evan Cheng64d80e32007-07-19 01:14:50 +0000442def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000443 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000444 [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2))),
445 (implicit EFLAGS)]>;
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000446
447// Register-Integer Subtraction
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000448def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
449 (ins GR64:$src1, i64i8imm:$src2),
450 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000451 [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2)),
452 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000453def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
454 (ins GR64:$src1, i64i32imm:$src2),
455 "sub{q}\t{$src2, $dst|$dst, $src2}",
456 [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2)),
457 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000458} // isTwoAddress
459
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000460// Memory-Register Subtraction
Evan Cheng64d80e32007-07-19 01:14:50 +0000461def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000462 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000463 [(store (sub (load addr:$dst), GR64:$src2), addr:$dst),
464 (implicit EFLAGS)]>;
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000465
466// Memory-Integer Subtraction
Evan Cheng64d80e32007-07-19 01:14:50 +0000467def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000468 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000469 [(store (sub (load addr:$dst), i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +0000470 addr:$dst),
471 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000472def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
473 "sub{q}\t{$src2, $dst|$dst, $src2}",
474 [(store (sub (load addr:$dst), i64immSExt32:$src2),
475 addr:$dst),
476 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000477
Evan Cheng3154cb62007-10-05 17:59:57 +0000478let Uses = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000479let isTwoAddress = 1 in {
Dale Johannesen874ae252009-06-02 03:12:52 +0000480def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000481 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000482 [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000483
Dale Johannesen874ae252009-06-02 03:12:52 +0000484def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000485 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000486 [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000487
Dale Johannesen874ae252009-06-02 03:12:52 +0000488def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000489 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000490 [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
491def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +0000492 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000493 [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000494} // isTwoAddress
495
Evan Cheng64d80e32007-07-19 01:14:50 +0000496def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000497 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000498 [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000499def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000500 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000501 [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000502def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
503 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dale Johannesen874ae252009-06-02 03:12:52 +0000504 [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
Evan Cheng3154cb62007-10-05 17:59:57 +0000505} // Uses = [EFLAGS]
Evan Cheng24f2ea32007-09-14 21:48:26 +0000506} // Defs = [EFLAGS]
Evan Cheng25ab6902006-09-08 06:48:29 +0000507
508// Unsigned multiplication
Chris Lattnerba7e7562008-01-10 07:59:24 +0000509let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
Evan Cheng64d80e32007-07-19 01:14:50 +0000510def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
Evan Cheng071a2792007-09-11 19:55:27 +0000511 "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerba7e7562008-01-10 07:59:24 +0000512let mayLoad = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000513def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
Evan Cheng071a2792007-09-11 19:55:27 +0000514 "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
Evan Cheng25ab6902006-09-08 06:48:29 +0000515
516// Signed multiplication
Evan Cheng64d80e32007-07-19 01:14:50 +0000517def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
Evan Cheng071a2792007-09-11 19:55:27 +0000518 "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerba7e7562008-01-10 07:59:24 +0000519let mayLoad = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000520def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
Evan Cheng071a2792007-09-11 19:55:27 +0000521 "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
522}
Evan Cheng25ab6902006-09-08 06:48:29 +0000523
Evan Cheng24f2ea32007-09-14 21:48:26 +0000524let Defs = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000525let isTwoAddress = 1 in {
526let isCommutable = 1 in
Bill Wendlingd350e022008-12-12 21:15:41 +0000527// Register-Register Signed Integer Multiplication
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000528def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
529 (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000530 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000531 [(set GR64:$dst, (mul GR64:$src1, GR64:$src2)),
532 (implicit EFLAGS)]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +0000533
Bill Wendlingd350e022008-12-12 21:15:41 +0000534// Register-Memory Signed Integer Multiplication
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000535def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
536 (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000537 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000538 [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2))),
539 (implicit EFLAGS)]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +0000540} // isTwoAddress
541
542// Suprisingly enough, these are not two address instructions!
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000543
Bill Wendlingd350e022008-12-12 21:15:41 +0000544// Register-Integer Signed Integer Multiplication
Evan Cheng25ab6902006-09-08 06:48:29 +0000545def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
Evan Cheng64d80e32007-07-19 01:14:50 +0000546 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000547 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingd350e022008-12-12 21:15:41 +0000548 [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2)),
549 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000550def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
551 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
552 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
553 [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2)),
554 (implicit EFLAGS)]>;
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000555
Bill Wendlingd350e022008-12-12 21:15:41 +0000556// Memory-Integer Signed Integer Multiplication
Evan Cheng25ab6902006-09-08 06:48:29 +0000557def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
Evan Cheng64d80e32007-07-19 01:14:50 +0000558 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000559 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingab55ebd2008-12-12 00:56:36 +0000560 [(set GR64:$dst, (mul (load addr:$src1),
Bill Wendlingd350e022008-12-12 21:15:41 +0000561 i64immSExt8:$src2)),
562 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000563def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
564 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
565 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
566 [(set GR64:$dst, (mul (load addr:$src1),
567 i64immSExt32:$src2)),
568 (implicit EFLAGS)]>;
Evan Cheng24f2ea32007-09-14 21:48:26 +0000569} // Defs = [EFLAGS]
Evan Cheng25ab6902006-09-08 06:48:29 +0000570
571// Unsigned division / remainder
Evan Cheng24f2ea32007-09-14 21:48:26 +0000572let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
Evan Cheng64d80e32007-07-19 01:14:50 +0000573def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng071a2792007-09-11 19:55:27 +0000574 "div{q}\t$src", []>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000575// Signed division / remainder
Evan Cheng64d80e32007-07-19 01:14:50 +0000576def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng071a2792007-09-11 19:55:27 +0000577 "idiv{q}\t$src", []>;
Chris Lattnerba7e7562008-01-10 07:59:24 +0000578let mayLoad = 1 in {
579def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
580 "div{q}\t$src", []>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000581def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
Evan Cheng071a2792007-09-11 19:55:27 +0000582 "idiv{q}\t$src", []>;
583}
Chris Lattnerba7e7562008-01-10 07:59:24 +0000584}
Evan Cheng25ab6902006-09-08 06:48:29 +0000585
586// Unary instructions
Evan Cheng24f2ea32007-09-14 21:48:26 +0000587let Defs = [EFLAGS], CodeSize = 2 in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000588let isTwoAddress = 1 in
Dan Gohmanb1576f52007-07-31 20:11:57 +0000589def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000590 [(set GR64:$dst, (ineg GR64:$src)),
591 (implicit EFLAGS)]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000592def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000593 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
594 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000595
596let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohmanb1576f52007-07-31 20:11:57 +0000597def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000598 [(set GR64:$dst, (add GR64:$src, 1)),
599 (implicit EFLAGS)]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000600def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000601 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
602 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000603
604let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohmanb1576f52007-07-31 20:11:57 +0000605def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000606 [(set GR64:$dst, (add GR64:$src, -1)),
607 (implicit EFLAGS)]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000608def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000609 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
610 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000611
612// In 64-bit mode, single byte INC and DEC cannot be encoded.
613let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
614// Can transform into LEA.
Dan Gohmanb1576f52007-07-31 20:11:57 +0000615def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src), "inc{w}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000616 [(set GR16:$dst, (add GR16:$src, 1)),
617 (implicit EFLAGS)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000618 OpSize, Requires<[In64BitMode]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000619def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src), "inc{l}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000620 [(set GR32:$dst, (add GR32:$src, 1)),
621 (implicit EFLAGS)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000622 Requires<[In64BitMode]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000623def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src), "dec{w}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000624 [(set GR16:$dst, (add GR16:$src, -1)),
625 (implicit EFLAGS)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000626 OpSize, Requires<[In64BitMode]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000627def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000628 [(set GR32:$dst, (add GR32:$src, -1)),
629 (implicit EFLAGS)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000630 Requires<[In64BitMode]>;
631} // isConvertibleToThreeAddress
Evan Cheng66f71632007-10-19 21:23:22 +0000632
633// These are duplicates of their 32-bit counterparts. Only needed so X86 knows
634// how to unfold them.
635let isTwoAddress = 0, CodeSize = 2 in {
636 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000637 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
638 (implicit EFLAGS)]>,
Evan Cheng66f71632007-10-19 21:23:22 +0000639 OpSize, Requires<[In64BitMode]>;
640 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000641 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
642 (implicit EFLAGS)]>,
Evan Cheng66f71632007-10-19 21:23:22 +0000643 Requires<[In64BitMode]>;
644 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000645 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
646 (implicit EFLAGS)]>,
Evan Cheng66f71632007-10-19 21:23:22 +0000647 OpSize, Requires<[In64BitMode]>;
648 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000649 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
650 (implicit EFLAGS)]>,
Evan Cheng66f71632007-10-19 21:23:22 +0000651 Requires<[In64BitMode]>;
652}
Evan Cheng24f2ea32007-09-14 21:48:26 +0000653} // Defs = [EFLAGS], CodeSize
Evan Cheng25ab6902006-09-08 06:48:29 +0000654
655
Evan Cheng24f2ea32007-09-14 21:48:26 +0000656let Defs = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000657// Shift instructions
658let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000659let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000660def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000661 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000662 [(set GR64:$dst, (shl GR64:$src, CL))]>;
Evan Chengb952d1f2007-10-05 18:20:36 +0000663let isConvertibleToThreeAddress = 1 in // Can transform into LEA.
Evan Cheng64d80e32007-07-19 01:14:50 +0000664def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000665 "shl{q}\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000666 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
Chris Lattnerf9b3f372008-01-11 18:00:50 +0000667// NOTE: We don't use shifts of a register by one, because 'add reg,reg' is
668// cheaper.
Evan Cheng25ab6902006-09-08 06:48:29 +0000669} // isTwoAddress
670
Evan Cheng071a2792007-09-11 19:55:27 +0000671let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000672def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000673 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000674 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000675def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000676 "shl{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000677 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000678def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000679 "shl{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000680 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
681
682let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000683let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000684def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000685 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000686 [(set GR64:$dst, (srl GR64:$src, CL))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000687def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000688 "shr{q}\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000689 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000690def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000691 "shr{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000692 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
693} // isTwoAddress
694
Evan Cheng071a2792007-09-11 19:55:27 +0000695let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000696def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000697 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000698 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000699def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000700 "shr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000701 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000702def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000703 "shr{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000704 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
705
706let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000707let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000708def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000709 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000710 [(set GR64:$dst, (sra GR64:$src, CL))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000711def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000712 "sar{q}\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000713 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000714def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000715 "sar{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000716 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
717} // isTwoAddress
718
Evan Cheng071a2792007-09-11 19:55:27 +0000719let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000720def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000721 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000722 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000723def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000724 "sar{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000725 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000726def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000727 "sar{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000728 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
729
730// Rotate instructions
731let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000732let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000733def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000734 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000735 [(set GR64:$dst, (rotl GR64:$src, CL))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000736def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000737 "rol{q}\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000738 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000739def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000740 "rol{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000741 [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
742} // isTwoAddress
743
Evan Cheng071a2792007-09-11 19:55:27 +0000744let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000745def ROL64mCL : I<0xD3, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000746 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000747 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000748def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000749 "rol{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000750 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000751def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000752 "rol{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000753 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
754
755let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000756let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000757def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000758 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000759 [(set GR64:$dst, (rotr GR64:$src, CL))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000760def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000761 "ror{q}\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000762 [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000763def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000764 "ror{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000765 [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
766} // isTwoAddress
767
Evan Cheng071a2792007-09-11 19:55:27 +0000768let Uses = [CL] in
Evan Cheng64d80e32007-07-19 01:14:50 +0000769def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000770 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng071a2792007-09-11 19:55:27 +0000771 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000772def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000773 "ror{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +0000774 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000775def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000776 "ror{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000777 [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
778
779// Double shift instructions (generalizations of rotate)
780let isTwoAddress = 1 in {
Evan Cheng071a2792007-09-11 19:55:27 +0000781let Uses = [CL] in {
Evan Cheng64d80e32007-07-19 01:14:50 +0000782def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000783 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
784 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000785def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000786 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
787 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Cheng071a2792007-09-11 19:55:27 +0000788}
Evan Cheng25ab6902006-09-08 06:48:29 +0000789
790let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
791def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
Evan Cheng64d80e32007-07-19 01:14:50 +0000792 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000793 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
794 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
795 (i8 imm:$src3)))]>,
796 TB;
Evan Cheng25ab6902006-09-08 06:48:29 +0000797def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
Evan Cheng64d80e32007-07-19 01:14:50 +0000798 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000799 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
800 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
801 (i8 imm:$src3)))]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000802 TB;
803} // isCommutable
804} // isTwoAddress
805
Evan Cheng071a2792007-09-11 19:55:27 +0000806let Uses = [CL] in {
Evan Cheng64d80e32007-07-19 01:14:50 +0000807def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000808 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
809 [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
810 addr:$dst)]>, TB;
Evan Cheng64d80e32007-07-19 01:14:50 +0000811def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000812 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
813 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
814 addr:$dst)]>, TB;
Evan Cheng071a2792007-09-11 19:55:27 +0000815}
Evan Cheng25ab6902006-09-08 06:48:29 +0000816def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
Evan Cheng64d80e32007-07-19 01:14:50 +0000817 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000818 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
819 [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
820 (i8 imm:$src3)), addr:$dst)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000821 TB;
822def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
Evan Cheng64d80e32007-07-19 01:14:50 +0000823 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohmane47f1f92007-09-14 23:17:45 +0000824 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
825 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
826 (i8 imm:$src3)), addr:$dst)]>,
Evan Cheng25ab6902006-09-08 06:48:29 +0000827 TB;
Evan Cheng24f2ea32007-09-14 21:48:26 +0000828} // Defs = [EFLAGS]
Evan Cheng25ab6902006-09-08 06:48:29 +0000829
830//===----------------------------------------------------------------------===//
831// Logical Instructions...
832//
833
Evan Chenga095c972009-01-21 19:45:31 +0000834let isTwoAddress = 1 , AddedComplexity = 15 in
Dan Gohmanb1576f52007-07-31 20:11:57 +0000835def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000836 [(set GR64:$dst, (not GR64:$src))]>;
Dan Gohmanb1576f52007-07-31 20:11:57 +0000837def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
Evan Cheng25ab6902006-09-08 06:48:29 +0000838 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
839
Evan Cheng24f2ea32007-09-14 21:48:26 +0000840let Defs = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000841let isTwoAddress = 1 in {
842let isCommutable = 1 in
843def AND64rr : RI<0x21, MRMDestReg,
Evan Cheng64d80e32007-07-19 01:14:50 +0000844 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000845 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000846 [(set GR64:$dst, (and GR64:$src1, GR64:$src2)),
847 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000848def AND64rm : RI<0x23, MRMSrcMem,
Evan Cheng64d80e32007-07-19 01:14:50 +0000849 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000850 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000851 [(set GR64:$dst, (and GR64:$src1, (load addr:$src2))),
852 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000853def AND64ri8 : RIi8<0x83, MRM4r,
Evan Cheng64d80e32007-07-19 01:14:50 +0000854 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000855 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000856 [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2)),
857 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000858def AND64ri32 : RIi32<0x81, MRM4r,
859 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
860 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000861 [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2)),
862 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000863} // isTwoAddress
864
865def AND64mr : RI<0x21, MRMDestMem,
Evan Cheng64d80e32007-07-19 01:14:50 +0000866 (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000867 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000868 [(store (and (load addr:$dst), GR64:$src), addr:$dst),
869 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000870def AND64mi8 : RIi8<0x83, MRM4m,
Evan Cheng64d80e32007-07-19 01:14:50 +0000871 (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000872 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000873 [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst),
874 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000875def AND64mi32 : RIi32<0x81, MRM4m,
876 (outs), (ins i64mem:$dst, i64i32imm:$src),
877 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000878 [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
879 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000880
881let isTwoAddress = 1 in {
882let isCommutable = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000883def OR64rr : RI<0x09, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000884 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000885 [(set GR64:$dst, (or GR64:$src1, GR64:$src2)),
886 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000887def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000888 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000889 [(set GR64:$dst, (or GR64:$src1, (load addr:$src2))),
890 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000891def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000892 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000893 [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
894 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000895def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
896 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000897 [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
898 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000899} // isTwoAddress
900
Evan Cheng64d80e32007-07-19 01:14:50 +0000901def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000902 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000903 [(store (or (load addr:$dst), GR64:$src), addr:$dst),
904 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000905def OR64mi8 : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000906 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000907 [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst),
908 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000909def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src),
910 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000911 [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
912 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000913
914let isTwoAddress = 1 in {
Evan Chengb18ae3c2008-08-30 08:54:22 +0000915let isCommutable = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000916def XOR64rr : RI<0x31, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000917 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000918 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2)),
919 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000920def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000921 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000922 [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2))),
923 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000924def XOR64ri8 : RIi8<0x83, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
925 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000926 [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2)),
927 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000928def XOR64ri32 : RIi32<0x81, MRM6r,
Evan Cheng64d80e32007-07-19 01:14:50 +0000929 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000930 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000931 [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2)),
932 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000933} // isTwoAddress
934
Evan Cheng64d80e32007-07-19 01:14:50 +0000935def XOR64mr : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000936 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000937 [(store (xor (load addr:$dst), GR64:$src), addr:$dst),
938 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000939def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000940 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000941 [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst),
942 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000943def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
944 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman09a2609e2009-03-03 19:53:46 +0000945 [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
946 (implicit EFLAGS)]>;
Evan Cheng24f2ea32007-09-14 21:48:26 +0000947} // Defs = [EFLAGS]
Evan Cheng25ab6902006-09-08 06:48:29 +0000948
949//===----------------------------------------------------------------------===//
950// Comparison Instructions...
951//
952
953// Integer comparison
Evan Cheng24f2ea32007-09-14 21:48:26 +0000954let Defs = [EFLAGS] in {
Evan Cheng25ab6902006-09-08 06:48:29 +0000955let isCommutable = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +0000956def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000957 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000958 [(X86cmp (and GR64:$src1, GR64:$src2), 0),
959 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000960def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000961 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000962 [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0),
963 (implicit EFLAGS)]>;
964def TEST64ri32 : RIi32<0xF7, MRM0r, (outs),
965 (ins GR64:$src1, i64i32imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000966 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000967 [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0),
968 (implicit EFLAGS)]>;
969def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
970 (ins i64mem:$src1, i64i32imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000971 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000972 [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0),
973 (implicit EFLAGS)]>;
Evan Cheng25ab6902006-09-08 06:48:29 +0000974
Evan Cheng64d80e32007-07-19 01:14:50 +0000975def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000976 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000977 [(X86cmp GR64:$src1, GR64:$src2),
978 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000979def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000980 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000981 [(X86cmp (loadi64 addr:$src1), GR64:$src2),
982 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000983def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000984 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000985 [(X86cmp GR64:$src1, (loadi64 addr:$src2)),
986 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000987def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
988 "cmp{q}\t{$src2, $src1|$src1, $src2}",
989 [(X86cmp GR64:$src1, i64immSExt8:$src2),
990 (implicit EFLAGS)]>;
Evan Cheng64d80e32007-07-19 01:14:50 +0000991def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +0000992 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000993 [(X86cmp GR64:$src1, i64immSExt32:$src2),
Evan Cheng0488db92007-09-25 01:57:46 +0000994 (implicit EFLAGS)]>;
Evan Chenge5f62042007-09-29 00:00:36 +0000995def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
Evan Cheng0488db92007-09-25 01:57:46 +0000996 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Chenge5f62042007-09-29 00:00:36 +0000997 [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2),
Evan Cheng0488db92007-09-25 01:57:46 +0000998 (implicit EFLAGS)]>;
Dan Gohman018a34c2008-12-19 18:25:21 +0000999def CMP64mi32 : RIi32<0x81, MRM7m, (outs),
1000 (ins i64mem:$src1, i64i32imm:$src2),
1001 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1002 [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2),
1003 (implicit EFLAGS)]>;
Evan Cheng0488db92007-09-25 01:57:46 +00001004} // Defs = [EFLAGS]
1005
Dan Gohmanc7a37d42008-12-23 22:45:23 +00001006// Bit tests.
Dan Gohmanc7a37d42008-12-23 22:45:23 +00001007// TODO: BTC, BTR, and BTS
1008let Defs = [EFLAGS] in {
Chris Lattnerf1e9fd52008-12-25 01:32:49 +00001009def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohmanc7a37d42008-12-23 22:45:23 +00001010 "bt{q}\t{$src2, $src1|$src1, $src2}",
1011 [(X86bt GR64:$src1, GR64:$src2),
Chris Lattnerf1e9fd52008-12-25 01:32:49 +00001012 (implicit EFLAGS)]>, TB;
Dan Gohmanf31408d2009-01-13 23:23:30 +00001013
1014// Unlike with the register+register form, the memory+register form of the
1015// bt instruction does not ignore the high bits of the index. From ISel's
1016// perspective, this is pretty bizarre. Disable these instructions for now.
1017//def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1018// "bt{q}\t{$src2, $src1|$src1, $src2}",
1019// [(X86bt (loadi64 addr:$src1), GR64:$src2),
1020// (implicit EFLAGS)]>, TB;
Dan Gohman4afe15b2009-01-13 20:33:23 +00001021
1022def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1023 "bt{q}\t{$src2, $src1|$src1, $src2}",
1024 [(X86bt GR64:$src1, i64immSExt8:$src2),
1025 (implicit EFLAGS)]>, TB;
1026// Note that these instructions don't need FastBTMem because that
1027// only applies when the other operand is in a register. When it's
1028// an immediate, bt is still fast.
1029def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1030 "bt{q}\t{$src2, $src1|$src1, $src2}",
1031 [(X86bt (loadi64 addr:$src1), i64immSExt8:$src2),
1032 (implicit EFLAGS)]>, TB;
Dan Gohmanc7a37d42008-12-23 22:45:23 +00001033} // Defs = [EFLAGS]
1034
Evan Cheng25ab6902006-09-08 06:48:29 +00001035// Conditional moves
Evan Cheng0488db92007-09-25 01:57:46 +00001036let Uses = [EFLAGS], isTwoAddress = 1 in {
Evan Cheng7ad42d92007-10-05 23:13:21 +00001037let isCommutable = 1 in {
Evan Cheng25ab6902006-09-08 06:48:29 +00001038def CMOVB64rr : RI<0x42, MRMSrcReg, // if <u, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001039 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001040 "cmovb\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001041 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001042 X86_COND_B, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001043def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001044 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001045 "cmovae\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001046 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001047 X86_COND_AE, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001048def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001049 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001050 "cmove\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001051 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001052 X86_COND_E, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001053def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001054 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001055 "cmovne\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001056 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001057 X86_COND_NE, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001058def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001059 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001060 "cmovbe\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001061 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001062 X86_COND_BE, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001063def CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001064 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001065 "cmova\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001066 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001067 X86_COND_A, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001068def CMOVL64rr : RI<0x4C, MRMSrcReg, // if <s, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001069 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001070 "cmovl\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001071 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001072 X86_COND_L, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001073def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001074 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001075 "cmovge\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001076 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001077 X86_COND_GE, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001078def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001079 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001080 "cmovle\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001081 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001082 X86_COND_LE, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001083def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001084 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001085 "cmovg\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001086 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001087 X86_COND_G, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001088def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001089 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001090 "cmovs\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001091 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001092 X86_COND_S, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001093def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001094 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001095 "cmovns\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001096 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001097 X86_COND_NS, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001098def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001099 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001100 "cmovp\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001101 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001102 X86_COND_P, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001103def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64
Evan Cheng64d80e32007-07-19 01:14:50 +00001104 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001105 "cmovnp\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001106 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Chenge5f62042007-09-29 00:00:36 +00001107 X86_COND_NP, EFLAGS))]>, TB;
Dan Gohman305fceb2009-01-07 00:35:10 +00001108def CMOVO64rr : RI<0x40, MRMSrcReg, // if overflow, GR64 = GR64
1109 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1110 "cmovo\t{$src2, $dst|$dst, $src2}",
1111 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1112 X86_COND_O, EFLAGS))]>, TB;
1113def CMOVNO64rr : RI<0x41, MRMSrcReg, // if !overflow, GR64 = GR64
1114 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1115 "cmovno\t{$src2, $dst|$dst, $src2}",
1116 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1117 X86_COND_NO, EFLAGS))]>, TB;
Evan Cheng7ad42d92007-10-05 23:13:21 +00001118} // isCommutable = 1
1119
1120def CMOVB64rm : RI<0x42, MRMSrcMem, // if <u, GR64 = [mem64]
1121 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1122 "cmovb\t{$src2, $dst|$dst, $src2}",
1123 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1124 X86_COND_B, EFLAGS))]>, TB;
1125def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64]
1126 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1127 "cmovae\t{$src2, $dst|$dst, $src2}",
1128 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1129 X86_COND_AE, EFLAGS))]>, TB;
1130def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64]
1131 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1132 "cmove\t{$src2, $dst|$dst, $src2}",
1133 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1134 X86_COND_E, EFLAGS))]>, TB;
1135def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64]
1136 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1137 "cmovne\t{$src2, $dst|$dst, $src2}",
1138 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1139 X86_COND_NE, EFLAGS))]>, TB;
1140def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64]
1141 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1142 "cmovbe\t{$src2, $dst|$dst, $src2}",
1143 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1144 X86_COND_BE, EFLAGS))]>, TB;
1145def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64]
1146 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1147 "cmova\t{$src2, $dst|$dst, $src2}",
1148 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1149 X86_COND_A, EFLAGS))]>, TB;
1150def CMOVL64rm : RI<0x4C, MRMSrcMem, // if <s, GR64 = [mem64]
1151 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1152 "cmovl\t{$src2, $dst|$dst, $src2}",
1153 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1154 X86_COND_L, EFLAGS))]>, TB;
1155def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64]
1156 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1157 "cmovge\t{$src2, $dst|$dst, $src2}",
1158 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1159 X86_COND_GE, EFLAGS))]>, TB;
1160def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64]
1161 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1162 "cmovle\t{$src2, $dst|$dst, $src2}",
1163 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1164 X86_COND_LE, EFLAGS))]>, TB;
1165def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64]
1166 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1167 "cmovg\t{$src2, $dst|$dst, $src2}",
1168 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1169 X86_COND_G, EFLAGS))]>, TB;
1170def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64]
1171 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1172 "cmovs\t{$src2, $dst|$dst, $src2}",
1173 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1174 X86_COND_S, EFLAGS))]>, TB;
1175def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64]
1176 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1177 "cmovns\t{$src2, $dst|$dst, $src2}",
1178 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1179 X86_COND_NS, EFLAGS))]>, TB;
1180def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64]
1181 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1182 "cmovp\t{$src2, $dst|$dst, $src2}",
1183 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1184 X86_COND_P, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001185def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64]
Evan Cheng64d80e32007-07-19 01:14:50 +00001186 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001187 "cmovnp\t{$src2, $dst|$dst, $src2}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001188 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
Evan Cheng0488db92007-09-25 01:57:46 +00001189 X86_COND_NP, EFLAGS))]>, TB;
Dan Gohman305fceb2009-01-07 00:35:10 +00001190def CMOVO64rm : RI<0x40, MRMSrcMem, // if overflow, GR64 = [mem64]
1191 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1192 "cmovo\t{$src2, $dst|$dst, $src2}",
1193 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1194 X86_COND_O, EFLAGS))]>, TB;
1195def CMOVNO64rm : RI<0x41, MRMSrcMem, // if !overflow, GR64 = [mem64]
1196 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1197 "cmovno\t{$src2, $dst|$dst, $src2}",
1198 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1199 X86_COND_NO, EFLAGS))]>, TB;
Evan Cheng25ab6902006-09-08 06:48:29 +00001200} // isTwoAddress
1201
1202//===----------------------------------------------------------------------===//
1203// Conversion Instructions...
1204//
1205
1206// f64 -> signed i64
Evan Cheng64d80e32007-07-19 01:14:50 +00001207def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001208 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001209 [(set GR64:$dst,
1210 (int_x86_sse2_cvtsd2si64 VR128:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001211def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001212 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001213 [(set GR64:$dst, (int_x86_sse2_cvtsd2si64
1214 (load addr:$src)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001215def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001216 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001217 [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001218def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001219 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001220 [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001221def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001222 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001223 [(set GR64:$dst,
1224 (int_x86_sse2_cvttsd2si64 VR128:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001225def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001226 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001227 [(set GR64:$dst,
1228 (int_x86_sse2_cvttsd2si64
1229 (load addr:$src)))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +00001230
1231// Signed i64 -> f64
Evan Cheng64d80e32007-07-19 01:14:50 +00001232def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001233 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001234 [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001235def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001236 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001237 [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng90e9d4e2008-01-11 07:37:44 +00001238
Evan Cheng25ab6902006-09-08 06:48:29 +00001239let isTwoAddress = 1 in {
1240def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
Evan Cheng64d80e32007-07-19 01:14:50 +00001241 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001242 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001243 [(set VR128:$dst,
1244 (int_x86_sse2_cvtsi642sd VR128:$src1,
1245 GR64:$src2))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +00001246def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
Evan Cheng64d80e32007-07-19 01:14:50 +00001247 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001248 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001249 [(set VR128:$dst,
1250 (int_x86_sse2_cvtsi642sd VR128:$src1,
1251 (loadi64 addr:$src2)))]>;
Evan Cheng25ab6902006-09-08 06:48:29 +00001252} // isTwoAddress
1253
1254// Signed i64 -> f32
Evan Cheng64d80e32007-07-19 01:14:50 +00001255def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001256 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001257 [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001258def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001259 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001260 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng90e9d4e2008-01-11 07:37:44 +00001261
1262let isTwoAddress = 1 in {
1263 def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg,
1264 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1265 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1266 [(set VR128:$dst,
1267 (int_x86_sse_cvtsi642ss VR128:$src1,
1268 GR64:$src2))]>;
1269 def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem,
1270 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1271 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1272 [(set VR128:$dst,
1273 (int_x86_sse_cvtsi642ss VR128:$src1,
1274 (loadi64 addr:$src2)))]>;
1275}
Evan Cheng25ab6902006-09-08 06:48:29 +00001276
1277// f32 -> signed i64
Evan Cheng64d80e32007-07-19 01:14:50 +00001278def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001279 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001280 [(set GR64:$dst,
1281 (int_x86_sse_cvtss2si64 VR128:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001282def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001283 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001284 [(set GR64:$dst, (int_x86_sse_cvtss2si64
1285 (load addr:$src)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001286def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001287 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001288 [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001289def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001290 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001291 [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001292def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001293 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001294 [(set GR64:$dst,
1295 (int_x86_sse_cvttss2si64 VR128:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001296def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001297 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6a20cf02007-07-23 03:07:27 +00001298 [(set GR64:$dst,
1299 (int_x86_sse_cvttss2si64 (load addr:$src)))]>;
1300
Evan Cheng25ab6902006-09-08 06:48:29 +00001301//===----------------------------------------------------------------------===//
1302// Alias Instructions
1303//===----------------------------------------------------------------------===//
1304
Dan Gohman95906242007-09-17 14:55:08 +00001305// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
1306// equivalent due to implicit zero-extending, and it sometimes has a smaller
1307// encoding.
Chris Lattner9ac75422009-07-14 20:19:57 +00001308// FIXME: AddedComplexity gives this a higher priority than MOV64ri32. Remove
Evan Cheng25ab6902006-09-08 06:48:29 +00001309// when we have a better way to specify isel priority.
Chris Lattner9ac75422009-07-14 20:19:57 +00001310let AddedComplexity = 1 in
1311def : Pat<(i64 0),
Chris Lattner6ef40b12009-07-16 06:31:37 +00001312 (SUBREG_TO_REG (i64 0), (MOV32r0), x86_subreg_32bit)>;
Chris Lattner9ac75422009-07-14 20:19:57 +00001313
Evan Cheng25ab6902006-09-08 06:48:29 +00001314
1315// Materialize i64 constant where top 32-bits are zero.
Evan Chengb3379fb2009-02-05 08:42:55 +00001316let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Cheng64d80e32007-07-19 01:14:50 +00001317def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001318 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
Evan Cheng25ab6902006-09-08 06:48:29 +00001319 [(set GR64:$dst, i64immZExt32:$src)]>;
1320
Anton Korobeynikov6625eff2008-05-04 21:36:32 +00001321//===----------------------------------------------------------------------===//
1322// Thread Local Storage Instructions
1323//===----------------------------------------------------------------------===//
1324
Rafael Espindola15f1b662009-04-24 12:59:40 +00001325// All calls clobber the non-callee saved registers. RSP is marked as
1326// a use to prevent stack-pointer assignments that appear immediately
1327// before calls from potentially appearing dead.
1328let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
1329 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
1330 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
1331 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
1332 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
1333 Uses = [RSP] in
Chris Lattner5c0b16d2009-06-20 20:38:48 +00001334def TLS_addr64 : I<0, Pseudo, (outs), (ins lea64mem:$sym),
Dan Gohman4d47b9b2009-04-27 15:13:28 +00001335 ".byte\t0x66; "
Chris Lattner5c0b16d2009-06-20 20:38:48 +00001336 "leaq\t$sym(%rip), %rdi; "
Dan Gohman4d47b9b2009-04-27 15:13:28 +00001337 ".word\t0x6666; "
1338 "rex64; "
1339 "call\t__tls_get_addr@PLT",
Chris Lattner5c0b16d2009-06-20 20:38:48 +00001340 [(X86tlsaddr tls64addr:$sym)]>,
Rafael Espindola2ee3db32009-04-17 14:35:58 +00001341 Requires<[In64BitMode]>;
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001342
Nate Begeman51a04372009-01-26 01:24:32 +00001343let AddedComplexity = 5 in
1344def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1345 "movq\t%gs:$src, $dst",
1346 [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
1347
Chris Lattner1777d0c2009-05-05 18:52:19 +00001348let AddedComplexity = 5 in
1349def MOV64FSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1350 "movq\t%fs:$src, $dst",
1351 [(set GR64:$dst, (fsload addr:$src))]>, SegFS;
1352
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001353//===----------------------------------------------------------------------===//
1354// Atomic Instructions
1355//===----------------------------------------------------------------------===//
1356
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001357let Defs = [RAX, EFLAGS], Uses = [RAX] in {
Evan Cheng7e032802008-04-18 20:55:36 +00001358def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
Dan Gohman4d47b9b2009-04-27 15:13:28 +00001359 "lock\n\t"
1360 "cmpxchgq\t$swap,$ptr",
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001361 [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
1362}
1363
Dan Gohman165660e2008-08-06 15:52:50 +00001364let Constraints = "$val = $dst" in {
1365let Defs = [EFLAGS] in
Evan Cheng7e032802008-04-18 20:55:36 +00001366def LXADD64 : RI<0xC1, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Dan Gohman4d47b9b2009-04-27 15:13:28 +00001367 "lock\n\t"
1368 "xadd\t$val, $ptr",
Mon P Wang28873102008-06-25 08:15:39 +00001369 [(set GR64:$dst, (atomic_load_add_64 addr:$ptr, GR64:$val))]>,
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001370 TB, LOCK;
Evan Cheng94d7b022008-04-19 02:05:42 +00001371def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Bill Wendling108ecf32008-08-19 23:09:18 +00001372 "xchg\t$val, $ptr",
Evan Cheng94d7b022008-04-19 02:05:42 +00001373 [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001374}
1375
Dale Johannesena99e3842008-08-20 00:48:50 +00001376// Atomic exchange, and, or, xor
1377let Constraints = "$val = $dst", Defs = [EFLAGS],
1378 usesCustomDAGSchedInserter = 1 in {
1379def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001380 "#ATOMAND64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001381 [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001382def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001383 "#ATOMOR64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001384 [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001385def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001386 "#ATOMXOR64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001387 [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001388def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001389 "#ATOMNAND64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001390 [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001391def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001392 "#ATOMMIN64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001393 [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001394def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001395 "#ATOMMAX64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001396 [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001397def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001398 "#ATOMUMIN64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001399 [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001400def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewycky6ecf5ce2008-12-07 03:49:52 +00001401 "#ATOMUMAX64 PSEUDO!",
Dale Johannesene00a8a22008-08-28 02:44:49 +00001402 [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>;
Dale Johannesena99e3842008-08-20 00:48:50 +00001403}
Andrew Lenhartha76e2f02008-03-04 21:13:33 +00001404
Evan Cheng25ab6902006-09-08 06:48:29 +00001405//===----------------------------------------------------------------------===//
1406// Non-Instruction Patterns
1407//===----------------------------------------------------------------------===//
1408
Chris Lattner25142782009-07-11 22:50:33 +00001409// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable when not in small
1410// code model mode, should use 'movabs'. FIXME: This is really a hack, the
1411// 'movabs' predicate should handle this sort of thing.
Evan Cheng0085a282006-11-30 21:55:46 +00001412def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
Evan Cheng0085a282006-11-30 21:55:46 +00001413 (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
1414def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1415 (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
1416def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1417 (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
1418def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1419 (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
1420
Chris Lattner65a7a6f2009-07-11 23:17:29 +00001421// In static codegen with small code model, we can get the address of a label
1422// into a register with 'movl'. FIXME: This is a hack, the 'imm' predicate of
1423// the MOV64ri64i32 should accept these.
1424def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1425 (MOV64ri64i32 tconstpool :$dst)>, Requires<[SmallCode]>;
1426def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1427 (MOV64ri64i32 tjumptable :$dst)>, Requires<[SmallCode]>;
1428def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1429 (MOV64ri64i32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
1430def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1431 (MOV64ri64i32 texternalsym:$dst)>, Requires<[SmallCode]>;
1432
1433
Chris Lattner18c59872009-06-27 04:16:01 +00001434// If we have small model and -static mode, it is safe to store global addresses
1435// directly as immediates. FIXME: This is really a hack, the 'imm' predicate
Chris Lattner25142782009-07-11 22:50:33 +00001436// for MOV64mi32 should handle this sort of thing.
Evan Cheng28b514392006-12-05 19:50:18 +00001437def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1438 (MOV64mi32 addr:$dst, tconstpool:$src)>,
Dan Gohman6ecc2602009-06-03 00:37:20 +00001439 Requires<[SmallCode, IsStatic]>;
Evan Cheng28b514392006-12-05 19:50:18 +00001440def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1441 (MOV64mi32 addr:$dst, tjumptable:$src)>,
Dan Gohman6ecc2602009-06-03 00:37:20 +00001442 Requires<[SmallCode, IsStatic]>;
Evan Cheng0085a282006-11-30 21:55:46 +00001443def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
Evan Cheng28b514392006-12-05 19:50:18 +00001444 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
Dan Gohman6ecc2602009-06-03 00:37:20 +00001445 Requires<[SmallCode, IsStatic]>;
Evan Cheng0085a282006-11-30 21:55:46 +00001446def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
Evan Cheng28b514392006-12-05 19:50:18 +00001447 (MOV64mi32 addr:$dst, texternalsym:$src)>,
Dan Gohman6ecc2602009-06-03 00:37:20 +00001448 Requires<[SmallCode, IsStatic]>;
Evan Cheng0085a282006-11-30 21:55:46 +00001449
Evan Cheng25ab6902006-09-08 06:48:29 +00001450// Calls
1451// Direct PC relative function call for small code model. 32-bit displacement
1452// sign extended to 64-bit.
1453def : Pat<(X86call (i64 tglobaladdr:$dst)),
1454 (CALL64pcrel32 tglobaladdr:$dst)>;
1455def : Pat<(X86call (i64 texternalsym:$dst)),
1456 (CALL64pcrel32 texternalsym:$dst)>;
1457
1458def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1459 (CALL64pcrel32 tglobaladdr:$dst)>;
1460def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1461 (CALL64pcrel32 texternalsym:$dst)>;
1462
1463def : Pat<(X86tailcall GR64:$dst),
1464 (CALL64r GR64:$dst)>;
1465
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001466
1467// tailcall stuff
1468def : Pat<(X86tailcall GR32:$dst),
1469 (TAILCALL)>;
1470def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1471 (TAILCALL)>;
1472def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1473 (TAILCALL)>;
1474
1475def : Pat<(X86tcret GR64:$dst, imm:$off),
1476 (TCRETURNri64 GR64:$dst, imm:$off)>;
1477
1478def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1479 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1480
1481def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1482 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1483
Dan Gohman11f7bfb2007-09-17 14:35:24 +00001484// Comparisons.
1485
1486// TEST R,R is smaller than CMP R,0
Evan Chenge5f62042007-09-29 00:00:36 +00001487def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)),
Dan Gohman11f7bfb2007-09-17 14:35:24 +00001488 (TEST64rr GR64:$src1, GR64:$src1)>;
1489
Dan Gohmanfbb74862009-01-07 01:00:24 +00001490// Conditional moves with folded loads with operands swapped and conditions
1491// inverted.
1492def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
1493 (CMOVAE64rm GR64:$src2, addr:$src1)>;
1494def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
1495 (CMOVB64rm GR64:$src2, addr:$src1)>;
1496def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
1497 (CMOVNE64rm GR64:$src2, addr:$src1)>;
1498def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
1499 (CMOVE64rm GR64:$src2, addr:$src1)>;
1500def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
1501 (CMOVA64rm GR64:$src2, addr:$src1)>;
1502def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
1503 (CMOVBE64rm GR64:$src2, addr:$src1)>;
1504def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
1505 (CMOVGE64rm GR64:$src2, addr:$src1)>;
1506def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
1507 (CMOVL64rm GR64:$src2, addr:$src1)>;
1508def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
1509 (CMOVG64rm GR64:$src2, addr:$src1)>;
1510def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
1511 (CMOVLE64rm GR64:$src2, addr:$src1)>;
1512def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
1513 (CMOVNP64rm GR64:$src2, addr:$src1)>;
1514def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
1515 (CMOVP64rm GR64:$src2, addr:$src1)>;
1516def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
1517 (CMOVNS64rm GR64:$src2, addr:$src1)>;
1518def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
1519 (CMOVS64rm GR64:$src2, addr:$src1)>;
1520def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
1521 (CMOVNO64rm GR64:$src2, addr:$src1)>;
1522def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
1523 (CMOVO64rm GR64:$src2, addr:$src1)>;
Christopher Lamb6634e262008-03-13 05:47:01 +00001524
Duncan Sandsf9c98e62008-01-23 20:39:46 +00001525// zextload bool -> zextload byte
Evan Cheng25ab6902006-09-08 06:48:29 +00001526def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1527
1528// extload
Dan Gohman7deb1712008-08-27 17:33:15 +00001529// When extloading from 16-bit and smaller memory locations into 64-bit registers,
1530// use zero-extending loads so that the entire 64-bit register is defined, avoiding
1531// partial-register updates.
1532def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1533def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
1534def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1535// For other extloads, use subregs, since the high contents of the register are
1536// defined after an extload.
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001537def : Pat<(extloadi64i32 addr:$src),
1538 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
1539 x86_subreg_32bit)>;
1540def : Pat<(extloadi16i1 addr:$src),
1541 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1542 x86_subreg_8bit)>,
1543 Requires<[In64BitMode]>;
1544def : Pat<(extloadi16i8 addr:$src),
1545 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1546 x86_subreg_8bit)>,
1547 Requires<[In64BitMode]>;
Evan Cheng25ab6902006-09-08 06:48:29 +00001548
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001549// anyext
1550def : Pat<(i64 (anyext GR8:$src)),
1551 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
1552def : Pat<(i64 (anyext GR16:$src)),
1553 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
Christopher Lambc9298232008-03-16 03:12:01 +00001554def : Pat<(i64 (anyext GR32:$src)),
1555 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001556def : Pat<(i16 (anyext GR8:$src)),
1557 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1558 Requires<[In64BitMode]>;
1559def : Pat<(i32 (anyext GR8:$src)),
1560 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1561 Requires<[In64BitMode]>;
Evan Cheng25ab6902006-09-08 06:48:29 +00001562
1563//===----------------------------------------------------------------------===//
1564// Some peepholes
1565//===----------------------------------------------------------------------===//
1566
Dan Gohman63f97202008-10-17 01:33:43 +00001567// Odd encoding trick: -128 fits into an 8-bit immediate field while
1568// +128 doesn't, so in this special case use a sub instead of an add.
1569def : Pat<(add GR64:$src1, 128),
1570 (SUB64ri8 GR64:$src1, -128)>;
1571def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1572 (SUB64mi8 addr:$dst, -128)>;
1573
1574// The same trick applies for 32-bit immediate fields in 64-bit
1575// instructions.
1576def : Pat<(add GR64:$src1, 0x0000000080000000),
1577 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1578def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
1579 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1580
Dan Gohmane3d92062008-08-07 02:54:50 +00001581// r & (2^32-1) ==> movz
Dan Gohman63f97202008-10-17 01:33:43 +00001582def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001583 (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
Dan Gohman11ba3b12008-07-30 18:09:17 +00001584// r & (2^16-1) ==> movz
1585def : Pat<(and GR64:$src, 0xffff),
1586 (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
1587// r & (2^8-1) ==> movz
1588def : Pat<(and GR64:$src, 0xff),
1589 (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
Dan Gohman11ba3b12008-07-30 18:09:17 +00001590// r & (2^8-1) ==> movz
1591def : Pat<(and GR32:$src1, 0xff),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001592 (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>,
Dan Gohman11ba3b12008-07-30 18:09:17 +00001593 Requires<[In64BitMode]>;
1594// r & (2^8-1) ==> movz
1595def : Pat<(and GR16:$src1, 0xff),
1596 (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
1597 Requires<[In64BitMode]>;
Christopher Lamb6634e262008-03-13 05:47:01 +00001598
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001599// sext_inreg patterns
1600def : Pat<(sext_inreg GR64:$src, i32),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001601 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001602def : Pat<(sext_inreg GR64:$src, i16),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001603 (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001604def : Pat<(sext_inreg GR64:$src, i8),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001605 (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001606def : Pat<(sext_inreg GR32:$src, i8),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001607 (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001608 Requires<[In64BitMode]>;
1609def : Pat<(sext_inreg GR16:$src, i8),
1610 (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
1611 Requires<[In64BitMode]>;
1612
1613// trunc patterns
1614def : Pat<(i32 (trunc GR64:$src)),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001615 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001616def : Pat<(i16 (trunc GR64:$src)),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001617 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001618def : Pat<(i8 (trunc GR64:$src)),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001619 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>;
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001620def : Pat<(i8 (trunc GR32:$src)),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001621 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>,
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001622 Requires<[In64BitMode]>;
1623def : Pat<(i8 (trunc GR16:$src)),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001624 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>,
1625 Requires<[In64BitMode]>;
1626
1627// h-register tricks.
Dan Gohman2d98f062009-05-31 17:52:18 +00001628// For now, be conservative on x86-64 and use an h-register extract only if the
1629// value is immediately zero-extended or stored, which are somewhat common
1630// cases. This uses a bunch of code to prevent a register requiring a REX prefix
1631// from being allocated in the same instruction as the h register, as there's
1632// currently no way to describe this requirement to the register allocator.
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001633
1634// h-register extract and zero-extend.
1635def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
1636 (SUBREG_TO_REG
1637 (i64 0),
1638 (MOVZX32_NOREXrr8
Dan Gohman62417622009-04-27 16:33:14 +00001639 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001640 x86_subreg_8bit_hi)),
1641 x86_subreg_32bit)>;
1642def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
1643 (MOVZX32_NOREXrr8
Dan Gohman62417622009-04-27 16:33:14 +00001644 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001645 x86_subreg_8bit_hi))>,
1646 Requires<[In64BitMode]>;
1647def : Pat<(srl_su GR16:$src, (i8 8)),
1648 (EXTRACT_SUBREG
1649 (MOVZX32_NOREXrr8
Dan Gohman62417622009-04-27 16:33:14 +00001650 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001651 x86_subreg_8bit_hi)),
1652 x86_subreg_16bit)>,
1653 Requires<[In64BitMode]>;
Evan Chengcb219f02009-05-29 01:44:43 +00001654def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
1655 (MOVZX32_NOREXrr8
1656 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1657 x86_subreg_8bit_hi))>,
1658 Requires<[In64BitMode]>;
1659def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))),
1660 (SUBREG_TO_REG
1661 (i64 0),
1662 (MOVZX32_NOREXrr8
1663 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1664 x86_subreg_8bit_hi)),
1665 x86_subreg_32bit)>;
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001666
1667// h-register extract and store.
1668def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
1669 (MOV8mr_NOREX
1670 addr:$dst,
Dan Gohman62417622009-04-27 16:33:14 +00001671 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001672 x86_subreg_8bit_hi))>;
1673def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
1674 (MOV8mr_NOREX
1675 addr:$dst,
Dan Gohman62417622009-04-27 16:33:14 +00001676 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001677 x86_subreg_8bit_hi))>,
1678 Requires<[In64BitMode]>;
1679def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
1680 (MOV8mr_NOREX
1681 addr:$dst,
Dan Gohman62417622009-04-27 16:33:14 +00001682 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
Dan Gohman21e3dfb2009-04-13 16:09:41 +00001683 x86_subreg_8bit_hi))>,
Dan Gohman0bfa1bf2008-08-20 21:27:32 +00001684 Requires<[In64BitMode]>;
1685
Evan Cheng25ab6902006-09-08 06:48:29 +00001686// (shl x, 1) ==> (add x, x)
1687def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1688
Evan Chengeb9f8922008-08-30 02:03:58 +00001689// (shl x (and y, 63)) ==> (shl x, y)
1690def : Pat<(shl GR64:$src1, (and CL:$amt, 63)),
1691 (SHL64rCL GR64:$src1)>;
1692def : Pat<(store (shl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1693 (SHL64mCL addr:$dst)>;
1694
1695def : Pat<(srl GR64:$src1, (and CL:$amt, 63)),
1696 (SHR64rCL GR64:$src1)>;
1697def : Pat<(store (srl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1698 (SHR64mCL addr:$dst)>;
1699
1700def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
1701 (SAR64rCL GR64:$src1)>;
1702def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1703 (SAR64mCL addr:$dst)>;
1704
Evan Cheng25ab6902006-09-08 06:48:29 +00001705// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
1706def : Pat<(or (srl GR64:$src1, CL:$amt),
1707 (shl GR64:$src2, (sub 64, CL:$amt))),
1708 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1709
1710def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
1711 (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1712 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1713
Dan Gohman74feef22008-10-17 01:23:35 +00001714def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))),
1715 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1716 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1717
1718def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1719 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1720 addr:$dst),
1721 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1722
1723def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1724 (SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1725
1726def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
1727 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1728 (SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1729
Evan Cheng25ab6902006-09-08 06:48:29 +00001730// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
1731def : Pat<(or (shl GR64:$src1, CL:$amt),
1732 (srl GR64:$src2, (sub 64, CL:$amt))),
1733 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1734
1735def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
1736 (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1737 (SHLD64mrCL addr:$dst, GR64:$src2)>;
Evan Chengebf01d62006-11-16 23:33:25 +00001738
Dan Gohman74feef22008-10-17 01:23:35 +00001739def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))),
1740 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1741 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1742
1743def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1744 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1745 addr:$dst),
1746 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1747
1748def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1749 (SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1750
1751def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
1752 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1753 (SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1754
Chris Lattnera0668102007-05-17 06:35:11 +00001755// X86 specific add which produces a flag.
1756def : Pat<(addc GR64:$src1, GR64:$src2),
1757 (ADD64rr GR64:$src1, GR64:$src2)>;
1758def : Pat<(addc GR64:$src1, (load addr:$src2)),
1759 (ADD64rm GR64:$src1, addr:$src2)>;
Chris Lattnera0668102007-05-17 06:35:11 +00001760def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
1761 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman018a34c2008-12-19 18:25:21 +00001762def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
1763 (ADD64ri32 GR64:$src1, imm:$src2)>;
Chris Lattnera0668102007-05-17 06:35:11 +00001764
1765def : Pat<(subc GR64:$src1, GR64:$src2),
1766 (SUB64rr GR64:$src1, GR64:$src2)>;
1767def : Pat<(subc GR64:$src1, (load addr:$src2)),
1768 (SUB64rm GR64:$src1, addr:$src2)>;
Chris Lattnera0668102007-05-17 06:35:11 +00001769def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
1770 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman018a34c2008-12-19 18:25:21 +00001771def : Pat<(subc GR64:$src1, imm:$src2),
1772 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Chris Lattnera0668102007-05-17 06:35:11 +00001773
Bill Wendlingd350e022008-12-12 21:15:41 +00001774//===----------------------------------------------------------------------===//
Dan Gohman076aee32009-03-04 19:44:21 +00001775// EFLAGS-defining Patterns
Bill Wendlingd350e022008-12-12 21:15:41 +00001776//===----------------------------------------------------------------------===//
1777
Dan Gohman076aee32009-03-04 19:44:21 +00001778// Register-Register Addition with EFLAGS result
1779def : Pat<(parallel (X86add_flag GR64:$src1, GR64:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001780 (implicit EFLAGS)),
1781 (ADD64rr GR64:$src1, GR64:$src2)>;
1782
Dan Gohman076aee32009-03-04 19:44:21 +00001783// Register-Integer Addition with EFLAGS result
1784def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001785 (implicit EFLAGS)),
1786 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001787def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001788 (implicit EFLAGS)),
1789 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingd350e022008-12-12 21:15:41 +00001790
Dan Gohman076aee32009-03-04 19:44:21 +00001791// Register-Memory Addition with EFLAGS result
1792def : Pat<(parallel (X86add_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingd350e022008-12-12 21:15:41 +00001793 (implicit EFLAGS)),
1794 (ADD64rm GR64:$src1, addr:$src2)>;
1795
Dan Gohman076aee32009-03-04 19:44:21 +00001796// Memory-Register Addition with EFLAGS result
1797def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001798 addr:$dst),
1799 (implicit EFLAGS)),
1800 (ADD64mr addr:$dst, GR64:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001801def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001802 addr:$dst),
1803 (implicit EFLAGS)),
1804 (ADD64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001805def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001806 addr:$dst),
1807 (implicit EFLAGS)),
1808 (ADD64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingd350e022008-12-12 21:15:41 +00001809
Dan Gohman076aee32009-03-04 19:44:21 +00001810// Register-Register Subtraction with EFLAGS result
1811def : Pat<(parallel (X86sub_flag GR64:$src1, GR64:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001812 (implicit EFLAGS)),
1813 (SUB64rr GR64:$src1, GR64:$src2)>;
1814
Dan Gohman076aee32009-03-04 19:44:21 +00001815// Register-Memory Subtraction with EFLAGS result
1816def : Pat<(parallel (X86sub_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingd350e022008-12-12 21:15:41 +00001817 (implicit EFLAGS)),
1818 (SUB64rm GR64:$src1, addr:$src2)>;
1819
Dan Gohman076aee32009-03-04 19:44:21 +00001820// Register-Integer Subtraction with EFLAGS result
1821def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001822 (implicit EFLAGS)),
1823 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001824def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001825 (implicit EFLAGS)),
1826 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingd350e022008-12-12 21:15:41 +00001827
Dan Gohman076aee32009-03-04 19:44:21 +00001828// Memory-Register Subtraction with EFLAGS result
1829def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001830 addr:$dst),
1831 (implicit EFLAGS)),
1832 (SUB64mr addr:$dst, GR64:$src2)>;
1833
Dan Gohman076aee32009-03-04 19:44:21 +00001834// Memory-Integer Subtraction with EFLAGS result
1835def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001836 addr:$dst),
1837 (implicit EFLAGS)),
1838 (SUB64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001839def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001840 addr:$dst),
1841 (implicit EFLAGS)),
1842 (SUB64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingd350e022008-12-12 21:15:41 +00001843
Dan Gohman076aee32009-03-04 19:44:21 +00001844// Register-Register Signed Integer Multiplication with EFLAGS result
1845def : Pat<(parallel (X86smul_flag GR64:$src1, GR64:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001846 (implicit EFLAGS)),
1847 (IMUL64rr GR64:$src1, GR64:$src2)>;
1848
Dan Gohman076aee32009-03-04 19:44:21 +00001849// Register-Memory Signed Integer Multiplication with EFLAGS result
1850def : Pat<(parallel (X86smul_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingd350e022008-12-12 21:15:41 +00001851 (implicit EFLAGS)),
1852 (IMUL64rm GR64:$src1, addr:$src2)>;
1853
Dan Gohman076aee32009-03-04 19:44:21 +00001854// Register-Integer Signed Integer Multiplication with EFLAGS result
1855def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001856 (implicit EFLAGS)),
1857 (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001858def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001859 (implicit EFLAGS)),
1860 (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingd350e022008-12-12 21:15:41 +00001861
Dan Gohman076aee32009-03-04 19:44:21 +00001862// Memory-Integer Signed Integer Multiplication with EFLAGS result
1863def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt8:$src2),
Bill Wendlingd350e022008-12-12 21:15:41 +00001864 (implicit EFLAGS)),
1865 (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
Dan Gohman076aee32009-03-04 19:44:21 +00001866def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt32:$src2),
Dan Gohman018a34c2008-12-19 18:25:21 +00001867 (implicit EFLAGS)),
1868 (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
Chris Lattnera0668102007-05-17 06:35:11 +00001869
Dan Gohman076aee32009-03-04 19:44:21 +00001870// INC and DEC with EFLAGS result. Note that these do not set CF.
Dan Gohman1f4af262009-03-05 21:32:23 +00001871def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)),
1872 (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1873def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst),
1874 (implicit EFLAGS)),
1875 (INC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1876def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)),
1877 (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1878def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst),
1879 (implicit EFLAGS)),
1880 (DEC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1881
1882def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)),
1883 (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1884def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst),
1885 (implicit EFLAGS)),
1886 (INC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1887def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)),
1888 (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1889def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst),
1890 (implicit EFLAGS)),
1891 (DEC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1892
Dan Gohman076aee32009-03-04 19:44:21 +00001893def : Pat<(parallel (X86inc_flag GR64:$src), (implicit EFLAGS)),
1894 (INC64r GR64:$src)>;
1895def : Pat<(parallel (store (i64 (X86inc_flag (loadi64 addr:$dst))), addr:$dst),
1896 (implicit EFLAGS)),
1897 (INC64m addr:$dst)>;
1898def : Pat<(parallel (X86dec_flag GR64:$src), (implicit EFLAGS)),
1899 (DEC64r GR64:$src)>;
1900def : Pat<(parallel (store (i64 (X86dec_flag (loadi64 addr:$dst))), addr:$dst),
1901 (implicit EFLAGS)),
1902 (DEC64m addr:$dst)>;
1903
Evan Chengebf01d62006-11-16 23:33:25 +00001904//===----------------------------------------------------------------------===//
1905// X86-64 SSE Instructions
1906//===----------------------------------------------------------------------===//
1907
1908// Move instructions...
1909
Evan Cheng64d80e32007-07-19 01:14:50 +00001910def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001911 "mov{d|q}\t{$src, $dst|$dst, $src}",
Evan Chengebf01d62006-11-16 23:33:25 +00001912 [(set VR128:$dst,
1913 (v2i64 (scalar_to_vector GR64:$src)))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001914def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001915 "mov{d|q}\t{$src, $dst|$dst, $src}",
Evan Chengebf01d62006-11-16 23:33:25 +00001916 [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
1917 (iPTR 0)))]>;
Evan Cheng21b76122006-12-14 21:55:39 +00001918
Evan Cheng64d80e32007-07-19 01:14:50 +00001919def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001920 "mov{d|q}\t{$src, $dst|$dst, $src}",
Evan Cheng21b76122006-12-14 21:55:39 +00001921 [(set FR64:$dst, (bitconvert GR64:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001922def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Evan Chenge7321442008-08-25 04:11:42 +00001923 "movq\t{$src, $dst|$dst, $src}",
Evan Cheng21b76122006-12-14 21:55:39 +00001924 [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
1925
Evan Cheng64d80e32007-07-19 01:14:50 +00001926def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohmanb1576f52007-07-31 20:11:57 +00001927 "mov{d|q}\t{$src, $dst|$dst, $src}",
Evan Cheng21b76122006-12-14 21:55:39 +00001928 [(set GR64:$dst, (bitconvert FR64:$src))]>;
Evan Cheng64d80e32007-07-19 01:14:50 +00001929def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
Evan Chenge7321442008-08-25 04:11:42 +00001930 "movq\t{$src, $dst|$dst, $src}",
Evan Cheng21b76122006-12-14 21:55:39 +00001931 [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
Nate Begeman63ec90a2008-02-03 07:18:54 +00001932
1933//===----------------------------------------------------------------------===//
1934// X86-64 SSE4.1 Instructions
1935//===----------------------------------------------------------------------===//
1936
Nate Begemancdd1eec2008-02-12 22:51:28 +00001937/// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
1938multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
Nate Begeman110e3b32008-10-29 23:07:17 +00001939 def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
Nate Begemancdd1eec2008-02-12 22:51:28 +00001940 (ins VR128:$src1, i32i8imm:$src2),
1941 !strconcat(OpcodeStr,
1942 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1943 [(set GR64:$dst,
1944 (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
Evan Cheng172b7942008-03-14 07:39:27 +00001945 def mr : SS4AIi8<opc, MRMDestMem, (outs),
Nate Begemancdd1eec2008-02-12 22:51:28 +00001946 (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
1947 !strconcat(OpcodeStr,
1948 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1949 [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
1950 addr:$dst)]>, OpSize, REX_W;
1951}
1952
1953defm PEXTRQ : SS41I_extract64<0x16, "pextrq">;
1954
1955let isTwoAddress = 1 in {
1956 multiclass SS41I_insert64<bits<8> opc, string OpcodeStr> {
Evan Cheng172b7942008-03-14 07:39:27 +00001957 def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
Nate Begemancdd1eec2008-02-12 22:51:28 +00001958 (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
1959 !strconcat(OpcodeStr,
1960 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1961 [(set VR128:$dst,
1962 (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
1963 OpSize, REX_W;
Evan Cheng172b7942008-03-14 07:39:27 +00001964 def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
Nate Begemancdd1eec2008-02-12 22:51:28 +00001965 (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
1966 !strconcat(OpcodeStr,
1967 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1968 [(set VR128:$dst,
1969 (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
1970 imm:$src3)))]>, OpSize, REX_W;
1971 }
1972}
1973
1974defm PINSRQ : SS41I_insert64<0x22, "pinsrq">;