blob: e84d1368f4636539d1ffa380af9880b92967367b [file] [log] [blame]
Chris Lattner2de8d2b2008-01-10 05:50:42 +00001//====- X86Instr64bit.td - Describe X86-64 Instructions ----*- tablegen -*-===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 Lattner2de8d2b2008-01-10 05:50:42 +000017// Operand Definitions.
Dan Gohmanf17a25c2007-07-18 16:29:46 +000018//
19
20// 64-bits but only 32 bits are significant.
21def i64i32imm : Operand<i64>;
22// 64-bits but only 8 bits are significant.
23def i64i8imm : Operand<i64>;
24
25def lea64mem : Operand<i64> {
Rafael Espindolabca99f72009-04-08 21:14:34 +000026 let PrintMethod = "printlea64mem";
Dan Gohmanf17a25c2007-07-18 16:29:46 +000027 let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm);
28}
29
30def lea64_32mem : Operand<i32> {
31 let PrintMethod = "printlea64_32mem";
32 let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
33}
34
35//===----------------------------------------------------------------------===//
Chris Lattner2de8d2b2008-01-10 05:50:42 +000036// Complex Pattern Definitions.
Dan Gohmanf17a25c2007-07-18 16:29:46 +000037//
38def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
Evan Chengc3495762009-03-30 21:36:47 +000039 [add, mul, X86mul_imm, shl, or, frameindex, X86Wrapper],
40 []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000041
42//===----------------------------------------------------------------------===//
Chris Lattner2de8d2b2008-01-10 05:50:42 +000043// Pattern fragments.
Dan Gohmanf17a25c2007-07-18 16:29:46 +000044//
45
Dan Gohmand16fdc02008-12-19 18:25:21 +000046def i64immSExt8 : PatLeaf<(i64 imm), [{
47 // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit
48 // sign extended field.
49 return (int64_t)N->getZExtValue() == (int8_t)N->getZExtValue();
50}]>;
51
Dan Gohmanf17a25c2007-07-18 16:29:46 +000052def i64immSExt32 : PatLeaf<(i64 imm), [{
53 // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
54 // sign extended field.
Dan Gohmanfaeb4a32008-09-12 16:56:44 +000055 return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
Dan Gohmanf17a25c2007-07-18 16:29:46 +000056}]>;
57
58def i64immZExt32 : PatLeaf<(i64 imm), [{
59 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
60 // unsignedsign extended field.
Dan Gohmanfaeb4a32008-09-12 16:56:44 +000061 return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
Dan Gohmanf17a25c2007-07-18 16:29:46 +000062}]>;
63
Dan Gohmanf17a25c2007-07-18 16:29:46 +000064def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
65def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
66def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
67
68def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
69def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
70def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
71def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
72
73def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
74def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
75def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
76def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
77
78//===----------------------------------------------------------------------===//
79// Instruction list...
80//
81
Dan Gohman01c9f772008-10-01 18:28:06 +000082// ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into
83// a stack adjustment and the codegen must know that they may modify the stack
84// pointer before prolog-epilog rewriting occurs.
85// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
86// sub / add which can clobber EFLAGS.
87let Defs = [RSP, EFLAGS], Uses = [RSP] in {
88def ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs), (ins i32imm:$amt),
89 "#ADJCALLSTACKDOWN",
Chris Lattnerfe5d4022008-10-11 22:08:30 +000090 [(X86callseq_start timm:$amt)]>,
Dan Gohman01c9f772008-10-01 18:28:06 +000091 Requires<[In64BitMode]>;
92def ADJCALLSTACKUP64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
93 "#ADJCALLSTACKUP",
Chris Lattnerfe5d4022008-10-11 22:08:30 +000094 [(X86callseq_end timm:$amt1, timm:$amt2)]>,
Dan Gohman01c9f772008-10-01 18:28:06 +000095 Requires<[In64BitMode]>;
96}
97
Dan Gohmanf17a25c2007-07-18 16:29:46 +000098//===----------------------------------------------------------------------===//
99// Call Instructions...
100//
Evan Cheng37e7c752007-07-21 00:34:19 +0000101let isCall = 1 in
Dan Gohman01c9f772008-10-01 18:28:06 +0000102 // All calls clobber the non-callee saved registers. RSP is marked as
103 // a use to prevent stack-pointer assignments that appear immediately
104 // before calls from potentially appearing dead. Uses for argument
105 // registers are added manually.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000106 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
Evan Cheng931a8f42008-01-29 19:34:22 +0000107 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000108 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
109 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
Dan Gohman9499cfe2008-10-01 04:14:30 +0000110 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
111 Uses = [RSP] in {
Chris Lattner79552392009-03-18 00:43:52 +0000112
113 // NOTE: this pattern doesn't match "X86call imm", because we do not know
114 // that the offset between an arbitrary immediate and the call will fit in
115 // the 32-bit pcrel field that we have.
Evan Cheng0af5a042009-03-12 18:15:39 +0000116 def CALL64pcrel32 : I<0xE8, RawFrm,
117 (outs), (ins i64i32imm:$dst, variable_ops),
Chris Lattner79552392009-03-18 00:43:52 +0000118 "call\t${dst:call}", []>,
Evan Cheng0af5a042009-03-12 18:15:39 +0000119 Requires<[In64BitMode]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000120 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
Dan Gohman91888f02007-07-31 20:11:57 +0000121 "call\t{*}$dst", [(X86call GR64:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000122 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
Dan Gohmanea4faba2008-05-29 21:50:34 +0000123 "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000124 }
125
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000126
127
128let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000129def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset,
130 variable_ops),
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000131 "#TC_RETURN $dst $offset",
132 []>;
133
134let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000135def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
136 variable_ops),
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000137 "#TC_RETURN $dst $offset",
138 []>;
139
140
141let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000142 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst),
143 "jmp{q}\t{*}$dst # TAILCALL",
144 []>;
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000145
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000146// Branches
Owen Andersonf8053082007-11-12 07:39:39 +0000147let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
Dan Gohman91888f02007-07-31 20:11:57 +0000148 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000149 [(brind GR64:$dst)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000150 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000151 [(brind (loadi64 addr:$dst))]>;
152}
153
154//===----------------------------------------------------------------------===//
Anton Korobeynikov1ec04ee2008-09-08 21:12:47 +0000155// EH Pseudo Instructions
156//
157let isTerminator = 1, isReturn = 1, isBarrier = 1,
158 hasCtrlDep = 1 in {
159def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
160 "ret\t#eh_return, addr: $addr",
161 [(X86ehret GR64:$addr)]>;
162
163}
164
165//===----------------------------------------------------------------------===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000166// Miscellaneous Instructions...
167//
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000168let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000169def LEAVE64 : I<0xC9, RawFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000170 (outs), (ins), "leave", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000171let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
172let mayLoad = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000173def POP64r : I<0x58, AddRegFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000174 (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000175let mayStore = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000176def PUSH64r : I<0x50, AddRegFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000177 (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
178}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000179
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000180let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
Evan Chengf1341312007-09-26 21:28:00 +0000181def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000182let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
Evan Chengf1341312007-09-26 21:28:00 +0000183def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
Evan Chengd8434332007-09-26 01:29:06 +0000184
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000185def LEA64_32r : I<0x8D, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000186 (outs GR32:$dst), (ins lea64_32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000187 "lea{l}\t{$src|$dst}, {$dst|$src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000188 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
189
Evan Cheng1ea8e6b2008-03-27 01:41:09 +0000190let isReMaterializable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000191def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000192 "lea{q}\t{$src|$dst}, {$dst|$src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000193 [(set GR64:$dst, lea64addr:$src)]>;
194
195let isTwoAddress = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000196def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000197 "bswap{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000198 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000199
Evan Cheng48679f42007-12-14 02:13:44 +0000200// Bit scan instructions.
201let Defs = [EFLAGS] in {
Evan Cheng4e33de92007-12-14 18:49:43 +0000202def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000203 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000204 [(set GR64:$dst, (X86bsf GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000205def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000206 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000207 [(set GR64:$dst, (X86bsf (loadi64 addr:$src))),
208 (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000209
Evan Cheng4e33de92007-12-14 18:49:43 +0000210def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000211 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000212 [(set GR64:$dst, (X86bsr GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000213def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000214 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000215 [(set GR64:$dst, (X86bsr (loadi64 addr:$src))),
216 (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000217} // Defs = [EFLAGS]
218
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000219// Repeat string ops
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000220let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in
Evan Chengb783fa32007-07-19 01:14:50 +0000221def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000222 [(X86rep_movs i64)]>, REP;
223let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in
Evan Chengb783fa32007-07-19 01:14:50 +0000224def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000225 [(X86rep_stos i64)]>, REP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000226
227//===----------------------------------------------------------------------===//
228// Move Instructions...
229//
230
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000231let neverHasSideEffects = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000232def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000233 "mov{q}\t{$src, $dst|$dst, $src}", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000234
Evan Chengd2b9d302008-06-25 01:16:38 +0000235let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000236def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000237 "movabs{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000238 [(set GR64:$dst, imm:$src)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000239def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000240 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000241 [(set GR64:$dst, i64immSExt32:$src)]>;
Dan Gohman8aef09b2007-09-07 21:32:51 +0000242}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000243
Dan Gohman5574cc72008-12-03 18:15:48 +0000244let canFoldAsLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000245def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000246 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000247 [(set GR64:$dst, (load addr:$src))]>;
248
Evan Chengb783fa32007-07-19 01:14:50 +0000249def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000250 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000251 [(store GR64:$src, addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000252def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000253 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000254 [(store i64immSExt32:$src, addr:$dst)]>;
255
256// Sign/Zero extenders
257
Dan Gohmanedde1992009-04-13 15:13:28 +0000258// MOVSX64rr8 always has a REX prefix and it has an 8-bit register
259// operand, which makes it a rare instruction with an 8-bit register
260// operand that can never access an h register. If support for h registers
261// were generalized, this would require a special register class.
Evan Chengb783fa32007-07-19 01:14:50 +0000262def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000263 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000264 [(set GR64:$dst, (sext GR8:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000265def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000266 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000267 [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000268def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000269 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000270 [(set GR64:$dst, (sext GR16:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000271def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000272 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000273 [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000274def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000275 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000276 [(set GR64:$dst, (sext GR32:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000277def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000278 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000279 [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
280
Dan Gohman9203ab42008-07-30 18:09:17 +0000281// Use movzbl instead of movzbq when the destination is a register; it's
282// equivalent due to implicit zero-extending, and it has a smaller encoding.
283def MOVZX64rr8 : I<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
284 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
285 [(set GR64:$dst, (zext GR8:$src))]>, TB;
286def MOVZX64rm8 : I<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
287 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
288 [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
289// Use movzwl instead of movzwq when the destination is a register; it's
290// equivalent due to implicit zero-extending, and it has a smaller encoding.
291def MOVZX64rr16: I<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
292 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
293 [(set GR64:$dst, (zext GR16:$src))]>, TB;
294def MOVZX64rm16: I<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
295 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
296 [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000297
Dan Gohman47a419d2008-08-07 02:54:50 +0000298// There's no movzlq instruction, but movl can be used for this purpose, using
Dan Gohman4cedb1c2009-04-08 00:15:30 +0000299// implicit zero-extension. The preferred way to do 32-bit-to-64-bit zero
300// extension on x86-64 is to use a SUBREG_TO_REG to utilize implicit
301// zero-extension, however this isn't possible when the 32-bit value is
302// defined by a truncate or is copied from something where the high bits aren't
303// necessarily all zero. In such cases, we fall back to these explicit zext
304// instructions.
Dan Gohman47a419d2008-08-07 02:54:50 +0000305def MOVZX64rr32 : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
306 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
307 [(set GR64:$dst, (zext GR32:$src))]>;
308def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
309 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
310 [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
311
Dan Gohman4cedb1c2009-04-08 00:15:30 +0000312// Any instruction that defines a 32-bit result leaves the high half of the
313// register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
314// be copying from a truncate, but any other 32-bit operation will zero-extend
315// up to 64 bits.
316def def32 : PatLeaf<(i32 GR32:$src), [{
317 return N->getOpcode() != ISD::TRUNCATE &&
318 N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
319 N->getOpcode() != ISD::CopyFromReg;
320}]>;
321
322// In the case of a 32-bit def that is known to implicitly zero-extend,
323// we can use a SUBREG_TO_REG.
324def : Pat<(i64 (zext def32:$src)),
325 (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
326
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000327let neverHasSideEffects = 1 in {
328 let Defs = [RAX], Uses = [EAX] in
329 def CDQE : RI<0x98, RawFrm, (outs), (ins),
330 "{cltq|cdqe}", []>; // RAX = signext(EAX)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000331
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000332 let Defs = [RAX,RDX], Uses = [RAX] in
333 def CQO : RI<0x99, RawFrm, (outs), (ins),
334 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
335}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000336
337//===----------------------------------------------------------------------===//
338// Arithmetic Instructions...
339//
340
Evan Cheng55687072007-09-14 21:48:26 +0000341let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000342let isTwoAddress = 1 in {
343let isConvertibleToThreeAddress = 1 in {
344let isCommutable = 1 in
Bill Wendlingae034ed2008-12-12 00:56:36 +0000345// Register-Register Addition
346def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
347 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000348 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
Bill Wendlingae034ed2008-12-12 00:56:36 +0000349 (implicit EFLAGS)]>;
350
351// Register-Integer Addition
Bill Wendlingae034ed2008-12-12 00:56:36 +0000352def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
353 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000354 [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)),
355 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000356def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
357 "add{q}\t{$src2, $dst|$dst, $src2}",
358 [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)),
359 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000360} // isConvertibleToThreeAddress
361
Bill Wendlingae034ed2008-12-12 00:56:36 +0000362// Register-Memory Addition
363def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
364 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000365 [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))),
Bill Wendlingae034ed2008-12-12 00:56:36 +0000366 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000367} // isTwoAddress
368
Bill Wendlingae034ed2008-12-12 00:56:36 +0000369// Memory-Register Addition
Evan Chengb783fa32007-07-19 01:14:50 +0000370def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000371 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000372 [(store (add (load addr:$dst), GR64:$src2), addr:$dst),
373 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000374def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000375 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000376 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst),
377 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000378def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
379 "add{q}\t{$src2, $dst|$dst, $src2}",
380 [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst),
381 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000382
Evan Cheng259471d2007-10-05 17:59:57 +0000383let Uses = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000384let isTwoAddress = 1 in {
385let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000386def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000387 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000388 [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000389
Evan Chengb783fa32007-07-19 01:14:50 +0000390def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000391 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000392 [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000393
Evan Chengb783fa32007-07-19 01:14:50 +0000394def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000395 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000396 [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000397def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
398 "adc{q}\t{$src2, $dst|$dst, $src2}",
399 [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000400} // isTwoAddress
401
Evan Chengb783fa32007-07-19 01:14:50 +0000402def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000403 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000404 [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000405def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000406 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling0c52d0a2008-12-02 00:07:05 +0000407 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000408def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
409 "adc{q}\t{$src2, $dst|$dst, $src2}",
410 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Evan Cheng259471d2007-10-05 17:59:57 +0000411} // Uses = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000412
413let isTwoAddress = 1 in {
Bill Wendlingae034ed2008-12-12 00:56:36 +0000414// Register-Register Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000415def SUB64rr : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000416 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000417 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2)),
418 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000419
420// Register-Memory Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000421def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000422 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000423 [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2))),
424 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000425
426// Register-Integer Subtraction
Bill Wendlingae034ed2008-12-12 00:56:36 +0000427def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
428 (ins GR64:$src1, i64i8imm:$src2),
429 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000430 [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2)),
431 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000432def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
433 (ins GR64:$src1, i64i32imm:$src2),
434 "sub{q}\t{$src2, $dst|$dst, $src2}",
435 [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2)),
436 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000437} // isTwoAddress
438
Bill Wendlingae034ed2008-12-12 00:56:36 +0000439// Memory-Register Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000440def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000441 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000442 [(store (sub (load addr:$dst), GR64:$src2), addr:$dst),
443 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000444
445// Memory-Integer Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000446def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000447 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingae034ed2008-12-12 00:56:36 +0000448 [(store (sub (load addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +0000449 addr:$dst),
450 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000451def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
452 "sub{q}\t{$src2, $dst|$dst, $src2}",
453 [(store (sub (load addr:$dst), i64immSExt32:$src2),
454 addr:$dst),
455 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000456
Evan Cheng259471d2007-10-05 17:59:57 +0000457let Uses = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000458let isTwoAddress = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000459def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000460 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000461 [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
462
Evan Chengb783fa32007-07-19 01:14:50 +0000463def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000464 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000465 [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
466
Evan Chengb783fa32007-07-19 01:14:50 +0000467def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000468 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000469 [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000470def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
471 "sbb{q}\t{$src2, $dst|$dst, $src2}",
472 [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000473} // isTwoAddress
474
Evan Chengb783fa32007-07-19 01:14:50 +0000475def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000476 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000477 [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000478def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000479 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000480 [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000481def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
482 "sbb{q}\t{$src2, $dst|$dst, $src2}",
483 [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
Evan Cheng259471d2007-10-05 17:59:57 +0000484} // Uses = [EFLAGS]
Evan Cheng55687072007-09-14 21:48:26 +0000485} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000486
487// Unsigned multiplication
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000488let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000489def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000490 "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000491let mayLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000492def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000493 "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000494
495// Signed multiplication
Evan Chengb783fa32007-07-19 01:14:50 +0000496def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000497 "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000498let mayLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000499def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000500 "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
501}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000502
Evan Cheng55687072007-09-14 21:48:26 +0000503let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000504let isTwoAddress = 1 in {
505let isCommutable = 1 in
Bill Wendlingf5399032008-12-12 21:15:41 +0000506// Register-Register Signed Integer Multiplication
Bill Wendlingae034ed2008-12-12 00:56:36 +0000507def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
508 (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000509 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000510 [(set GR64:$dst, (mul GR64:$src1, GR64:$src2)),
511 (implicit EFLAGS)]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000512
Bill Wendlingf5399032008-12-12 21:15:41 +0000513// Register-Memory Signed Integer Multiplication
Bill Wendlingae034ed2008-12-12 00:56:36 +0000514def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
515 (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000516 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000517 [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2))),
518 (implicit EFLAGS)]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000519} // isTwoAddress
520
521// Suprisingly enough, these are not two address instructions!
Bill Wendlingae034ed2008-12-12 00:56:36 +0000522
Bill Wendlingf5399032008-12-12 21:15:41 +0000523// Register-Integer Signed Integer Multiplication
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000524def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
Evan Chengb783fa32007-07-19 01:14:50 +0000525 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000526 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000527 [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2)),
528 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000529def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
530 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
531 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
532 [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2)),
533 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000534
Bill Wendlingf5399032008-12-12 21:15:41 +0000535// Memory-Integer Signed Integer Multiplication
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000536def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
Evan Chengb783fa32007-07-19 01:14:50 +0000537 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000538 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingae034ed2008-12-12 00:56:36 +0000539 [(set GR64:$dst, (mul (load addr:$src1),
Bill Wendlingf5399032008-12-12 21:15:41 +0000540 i64immSExt8:$src2)),
541 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000542def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
543 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
544 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
545 [(set GR64:$dst, (mul (load addr:$src1),
546 i64immSExt32:$src2)),
547 (implicit EFLAGS)]>;
Evan Cheng55687072007-09-14 21:48:26 +0000548} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000549
550// Unsigned division / remainder
Evan Cheng55687072007-09-14 21:48:26 +0000551let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000552def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000553 "div{q}\t$src", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000554// Signed division / remainder
Evan Chengb783fa32007-07-19 01:14:50 +0000555def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000556 "idiv{q}\t$src", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000557let mayLoad = 1 in {
558def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
559 "div{q}\t$src", []>;
Evan Chengb783fa32007-07-19 01:14:50 +0000560def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000561 "idiv{q}\t$src", []>;
562}
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000563}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000564
565// Unary instructions
Evan Cheng55687072007-09-14 21:48:26 +0000566let Defs = [EFLAGS], CodeSize = 2 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000567let isTwoAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000568def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000569 [(set GR64:$dst, (ineg GR64:$src)),
570 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000571def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000572 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
573 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000574
575let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000576def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000577 [(set GR64:$dst, (add GR64:$src, 1)),
578 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000579def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000580 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
581 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000582
583let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000584def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000585 [(set GR64:$dst, (add GR64:$src, -1)),
586 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000587def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000588 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
589 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000590
591// In 64-bit mode, single byte INC and DEC cannot be encoded.
592let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
593// Can transform into LEA.
Dan Gohman91888f02007-07-31 20:11:57 +0000594def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src), "inc{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000595 [(set GR16:$dst, (add GR16:$src, 1)),
596 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000597 OpSize, Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000598def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src), "inc{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000599 [(set GR32:$dst, (add GR32:$src, 1)),
600 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000601 Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000602def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src), "dec{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000603 [(set GR16:$dst, (add GR16:$src, -1)),
604 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000605 OpSize, Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000606def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000607 [(set GR32:$dst, (add GR32:$src, -1)),
608 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000609 Requires<[In64BitMode]>;
610} // isConvertibleToThreeAddress
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000611
612// These are duplicates of their 32-bit counterparts. Only needed so X86 knows
613// how to unfold them.
614let isTwoAddress = 0, CodeSize = 2 in {
615 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000616 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
617 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000618 OpSize, Requires<[In64BitMode]>;
619 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000620 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
621 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000622 Requires<[In64BitMode]>;
623 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000624 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
625 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000626 OpSize, Requires<[In64BitMode]>;
627 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000628 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
629 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000630 Requires<[In64BitMode]>;
631}
Evan Cheng55687072007-09-14 21:48:26 +0000632} // Defs = [EFLAGS], CodeSize
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000633
634
Evan Cheng55687072007-09-14 21:48:26 +0000635let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000636// Shift instructions
637let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000638let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000639def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000640 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000641 [(set GR64:$dst, (shl GR64:$src, CL))]>;
Evan Chenga98f6272007-10-05 18:20:36 +0000642let isConvertibleToThreeAddress = 1 in // Can transform into LEA.
Evan Chengb783fa32007-07-19 01:14:50 +0000643def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000644 "shl{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000645 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
Chris Lattnerf4005a82008-01-11 18:00:50 +0000646// NOTE: We don't use shifts of a register by one, because 'add reg,reg' is
647// cheaper.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000648} // isTwoAddress
649
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000650let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000651def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000652 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000653 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000654def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000655 "shl{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000656 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000657def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000658 "shl{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000659 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
660
661let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000662let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000663def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000664 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000665 [(set GR64:$dst, (srl GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000666def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000667 "shr{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000668 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000669def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000670 "shr{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000671 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
672} // isTwoAddress
673
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000674let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000675def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000676 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000677 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000678def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000679 "shr{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000680 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000681def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000682 "shr{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000683 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
684
685let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000686let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000687def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000688 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000689 [(set GR64:$dst, (sra GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000690def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000691 "sar{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000692 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000693def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000694 "sar{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000695 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
696} // isTwoAddress
697
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000698let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000699def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000700 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000701 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000702def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000703 "sar{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000704 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000705def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000706 "sar{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000707 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
708
709// Rotate instructions
710let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000711let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000712def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000713 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000714 [(set GR64:$dst, (rotl GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000715def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000716 "rol{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000717 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000718def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000719 "rol{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000720 [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
721} // isTwoAddress
722
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000723let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000724def ROL64mCL : I<0xD3, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000725 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000726 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000727def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000728 "rol{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000729 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000730def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000731 "rol{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000732 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
733
734let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000735let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000736def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000737 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000738 [(set GR64:$dst, (rotr GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000739def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000740 "ror{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000741 [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000742def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000743 "ror{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000744 [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
745} // isTwoAddress
746
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000747let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000748def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000749 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000750 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000751def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000752 "ror{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000753 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000754def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000755 "ror{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000756 [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
757
758// Double shift instructions (generalizations of rotate)
759let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000760let Uses = [CL] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000761def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000762 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
763 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000764def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000765 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
766 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000767}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000768
769let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
770def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000771 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000772 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
773 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
774 (i8 imm:$src3)))]>,
775 TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000776def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000777 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000778 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
779 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
780 (i8 imm:$src3)))]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000781 TB;
782} // isCommutable
783} // isTwoAddress
784
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000785let Uses = [CL] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000786def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000787 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
788 [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
789 addr:$dst)]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000790def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000791 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
792 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
793 addr:$dst)]>, TB;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000794}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000795def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000796 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000797 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
798 [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
799 (i8 imm:$src3)), addr:$dst)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000800 TB;
801def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000802 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000803 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
804 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
805 (i8 imm:$src3)), addr:$dst)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000806 TB;
Evan Cheng55687072007-09-14 21:48:26 +0000807} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000808
809//===----------------------------------------------------------------------===//
810// Logical Instructions...
811//
812
Evan Cheng5b51c242009-01-21 19:45:31 +0000813let isTwoAddress = 1 , AddedComplexity = 15 in
Dan Gohman91888f02007-07-31 20:11:57 +0000814def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000815 [(set GR64:$dst, (not GR64:$src))]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000816def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000817 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
818
Evan Cheng55687072007-09-14 21:48:26 +0000819let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000820let isTwoAddress = 1 in {
821let isCommutable = 1 in
822def AND64rr : RI<0x21, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000823 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000824 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000825 [(set GR64:$dst, (and GR64:$src1, GR64:$src2)),
826 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000827def AND64rm : RI<0x23, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000828 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000829 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000830 [(set GR64:$dst, (and GR64:$src1, (load addr:$src2))),
831 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000832def AND64ri8 : RIi8<0x83, MRM4r,
Evan Chengb783fa32007-07-19 01:14:50 +0000833 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000834 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000835 [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2)),
836 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000837def AND64ri32 : RIi32<0x81, MRM4r,
838 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
839 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000840 [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2)),
841 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000842} // isTwoAddress
843
844def AND64mr : RI<0x21, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000845 (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000846 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000847 [(store (and (load addr:$dst), GR64:$src), addr:$dst),
848 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000849def AND64mi8 : RIi8<0x83, MRM4m,
Evan Chengb783fa32007-07-19 01:14:50 +0000850 (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000851 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000852 [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst),
853 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000854def AND64mi32 : RIi32<0x81, MRM4m,
855 (outs), (ins i64mem:$dst, i64i32imm:$src),
856 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000857 [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
858 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000859
860let isTwoAddress = 1 in {
861let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000862def OR64rr : RI<0x09, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000863 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000864 [(set GR64:$dst, (or GR64:$src1, GR64:$src2)),
865 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000866def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000867 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000868 [(set GR64:$dst, (or GR64:$src1, (load addr:$src2))),
869 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000870def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000871 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000872 [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
873 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000874def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
875 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000876 [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
877 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000878} // isTwoAddress
879
Evan Chengb783fa32007-07-19 01:14:50 +0000880def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000881 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000882 [(store (or (load addr:$dst), GR64:$src), addr:$dst),
883 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000884def OR64mi8 : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000885 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000886 [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst),
887 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000888def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src),
889 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000890 [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
891 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000892
893let isTwoAddress = 1 in {
Evan Cheng0685efa2008-08-30 08:54:22 +0000894let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000895def XOR64rr : RI<0x31, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000896 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000897 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2)),
898 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000899def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000900 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000901 [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2))),
902 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000903def XOR64ri8 : RIi8<0x83, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
904 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000905 [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2)),
906 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000907def XOR64ri32 : RIi32<0x81, MRM6r,
Evan Chengb783fa32007-07-19 01:14:50 +0000908 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000909 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000910 [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2)),
911 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000912} // isTwoAddress
913
Evan Chengb783fa32007-07-19 01:14:50 +0000914def XOR64mr : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000915 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000916 [(store (xor (load addr:$dst), GR64:$src), addr:$dst),
917 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000918def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000919 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000920 [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst),
921 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000922def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
923 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000924 [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
925 (implicit EFLAGS)]>;
Evan Cheng55687072007-09-14 21:48:26 +0000926} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000927
928//===----------------------------------------------------------------------===//
929// Comparison Instructions...
930//
931
932// Integer comparison
Evan Cheng55687072007-09-14 21:48:26 +0000933let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000934let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000935def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000936 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000937 [(X86cmp (and GR64:$src1, GR64:$src2), 0),
938 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000939def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000940 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000941 [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0),
942 (implicit EFLAGS)]>;
943def TEST64ri32 : RIi32<0xF7, MRM0r, (outs),
944 (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000945 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000946 [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0),
947 (implicit EFLAGS)]>;
948def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
949 (ins i64mem:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000950 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000951 [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0),
952 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000953
Evan Chengb783fa32007-07-19 01:14:50 +0000954def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000955 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000956 [(X86cmp GR64:$src1, GR64:$src2),
957 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000958def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000959 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000960 [(X86cmp (loadi64 addr:$src1), GR64:$src2),
961 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000962def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000963 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000964 [(X86cmp GR64:$src1, (loadi64 addr:$src2)),
965 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000966def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
967 "cmp{q}\t{$src2, $src1|$src1, $src2}",
968 [(X86cmp GR64:$src1, i64immSExt8:$src2),
969 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000970def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000971 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000972 [(X86cmp GR64:$src1, i64immSExt32:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000973 (implicit EFLAGS)]>;
Evan Cheng621216e2007-09-29 00:00:36 +0000974def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000975 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000976 [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000977 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000978def CMP64mi32 : RIi32<0x81, MRM7m, (outs),
979 (ins i64mem:$src1, i64i32imm:$src2),
980 "cmp{q}\t{$src2, $src1|$src1, $src2}",
981 [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2),
982 (implicit EFLAGS)]>;
Evan Cheng950aac02007-09-25 01:57:46 +0000983} // Defs = [EFLAGS]
984
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000985// Bit tests.
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000986// TODO: BTC, BTR, and BTS
987let Defs = [EFLAGS] in {
Chris Lattner5a95cde2008-12-25 01:32:49 +0000988def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000989 "bt{q}\t{$src2, $src1|$src1, $src2}",
990 [(X86bt GR64:$src1, GR64:$src2),
Chris Lattner5a95cde2008-12-25 01:32:49 +0000991 (implicit EFLAGS)]>, TB;
Dan Gohman85a228c2009-01-13 23:23:30 +0000992
993// Unlike with the register+register form, the memory+register form of the
994// bt instruction does not ignore the high bits of the index. From ISel's
995// perspective, this is pretty bizarre. Disable these instructions for now.
996//def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
997// "bt{q}\t{$src2, $src1|$src1, $src2}",
998// [(X86bt (loadi64 addr:$src1), GR64:$src2),
999// (implicit EFLAGS)]>, TB;
Dan Gohman46fb1cf2009-01-13 20:33:23 +00001000
1001def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1002 "bt{q}\t{$src2, $src1|$src1, $src2}",
1003 [(X86bt GR64:$src1, i64immSExt8:$src2),
1004 (implicit EFLAGS)]>, TB;
1005// Note that these instructions don't need FastBTMem because that
1006// only applies when the other operand is in a register. When it's
1007// an immediate, bt is still fast.
1008def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1009 "bt{q}\t{$src2, $src1|$src1, $src2}",
1010 [(X86bt (loadi64 addr:$src1), i64immSExt8:$src2),
1011 (implicit EFLAGS)]>, TB;
Dan Gohman7fe9b7f2008-12-23 22:45:23 +00001012} // Defs = [EFLAGS]
1013
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001014// Conditional moves
Evan Cheng950aac02007-09-25 01:57:46 +00001015let Uses = [EFLAGS], isTwoAddress = 1 in {
Evan Cheng926658c2007-10-05 23:13:21 +00001016let isCommutable = 1 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001017def CMOVB64rr : RI<0x42, MRMSrcReg, // if <u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001018 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001019 "cmovb\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001020 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001021 X86_COND_B, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001022def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001023 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001024 "cmovae\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001025 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001026 X86_COND_AE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001027def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001028 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001029 "cmove\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001030 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001031 X86_COND_E, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001032def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001033 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001034 "cmovne\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001035 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001036 X86_COND_NE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001037def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001038 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001039 "cmovbe\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001040 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001041 X86_COND_BE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001042def CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001043 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001044 "cmova\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001045 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001046 X86_COND_A, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001047def CMOVL64rr : RI<0x4C, MRMSrcReg, // if <s, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001048 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001049 "cmovl\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001050 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001051 X86_COND_L, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001052def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001053 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001054 "cmovge\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001055 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001056 X86_COND_GE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001057def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001058 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001059 "cmovle\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001060 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001061 X86_COND_LE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001062def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001063 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001064 "cmovg\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001065 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001066 X86_COND_G, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001067def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001068 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001069 "cmovs\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001070 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001071 X86_COND_S, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001072def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001073 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001074 "cmovns\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001075 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001076 X86_COND_NS, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001077def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001078 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001079 "cmovp\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001080 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001081 X86_COND_P, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001082def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001083 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001084 "cmovnp\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001085 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001086 X86_COND_NP, EFLAGS))]>, TB;
Dan Gohman12fd4d72009-01-07 00:35:10 +00001087def CMOVO64rr : RI<0x40, MRMSrcReg, // if overflow, GR64 = GR64
1088 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1089 "cmovo\t{$src2, $dst|$dst, $src2}",
1090 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1091 X86_COND_O, EFLAGS))]>, TB;
1092def CMOVNO64rr : RI<0x41, MRMSrcReg, // if !overflow, GR64 = GR64
1093 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1094 "cmovno\t{$src2, $dst|$dst, $src2}",
1095 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1096 X86_COND_NO, EFLAGS))]>, TB;
Evan Cheng926658c2007-10-05 23:13:21 +00001097} // isCommutable = 1
1098
1099def CMOVB64rm : RI<0x42, MRMSrcMem, // if <u, GR64 = [mem64]
1100 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1101 "cmovb\t{$src2, $dst|$dst, $src2}",
1102 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1103 X86_COND_B, EFLAGS))]>, TB;
1104def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64]
1105 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1106 "cmovae\t{$src2, $dst|$dst, $src2}",
1107 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1108 X86_COND_AE, EFLAGS))]>, TB;
1109def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64]
1110 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1111 "cmove\t{$src2, $dst|$dst, $src2}",
1112 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1113 X86_COND_E, EFLAGS))]>, TB;
1114def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64]
1115 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1116 "cmovne\t{$src2, $dst|$dst, $src2}",
1117 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1118 X86_COND_NE, EFLAGS))]>, TB;
1119def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64]
1120 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1121 "cmovbe\t{$src2, $dst|$dst, $src2}",
1122 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1123 X86_COND_BE, EFLAGS))]>, TB;
1124def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64]
1125 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1126 "cmova\t{$src2, $dst|$dst, $src2}",
1127 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1128 X86_COND_A, EFLAGS))]>, TB;
1129def CMOVL64rm : RI<0x4C, MRMSrcMem, // if <s, GR64 = [mem64]
1130 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1131 "cmovl\t{$src2, $dst|$dst, $src2}",
1132 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1133 X86_COND_L, EFLAGS))]>, TB;
1134def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64]
1135 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1136 "cmovge\t{$src2, $dst|$dst, $src2}",
1137 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1138 X86_COND_GE, EFLAGS))]>, TB;
1139def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64]
1140 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1141 "cmovle\t{$src2, $dst|$dst, $src2}",
1142 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1143 X86_COND_LE, EFLAGS))]>, TB;
1144def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64]
1145 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1146 "cmovg\t{$src2, $dst|$dst, $src2}",
1147 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1148 X86_COND_G, EFLAGS))]>, TB;
1149def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64]
1150 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1151 "cmovs\t{$src2, $dst|$dst, $src2}",
1152 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1153 X86_COND_S, EFLAGS))]>, TB;
1154def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64]
1155 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1156 "cmovns\t{$src2, $dst|$dst, $src2}",
1157 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1158 X86_COND_NS, EFLAGS))]>, TB;
1159def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64]
1160 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1161 "cmovp\t{$src2, $dst|$dst, $src2}",
1162 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1163 X86_COND_P, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001164def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64]
Evan Chengb783fa32007-07-19 01:14:50 +00001165 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001166 "cmovnp\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001167 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +00001168 X86_COND_NP, EFLAGS))]>, TB;
Dan Gohman12fd4d72009-01-07 00:35:10 +00001169def CMOVO64rm : RI<0x40, MRMSrcMem, // if overflow, GR64 = [mem64]
1170 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1171 "cmovo\t{$src2, $dst|$dst, $src2}",
1172 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1173 X86_COND_O, EFLAGS))]>, TB;
1174def CMOVNO64rm : RI<0x41, MRMSrcMem, // if !overflow, GR64 = [mem64]
1175 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1176 "cmovno\t{$src2, $dst|$dst, $src2}",
1177 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1178 X86_COND_NO, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001179} // isTwoAddress
1180
1181//===----------------------------------------------------------------------===//
1182// Conversion Instructions...
1183//
1184
1185// f64 -> signed i64
Evan Chengb783fa32007-07-19 01:14:50 +00001186def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001187 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001188 [(set GR64:$dst,
1189 (int_x86_sse2_cvtsd2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001190def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001191 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001192 [(set GR64:$dst, (int_x86_sse2_cvtsd2si64
1193 (load addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001194def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001195 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001196 [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001197def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001198 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001199 [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001200def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001201 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001202 [(set GR64:$dst,
1203 (int_x86_sse2_cvttsd2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001204def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001205 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001206 [(set GR64:$dst,
1207 (int_x86_sse2_cvttsd2si64
1208 (load addr:$src)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001209
1210// Signed i64 -> f64
Evan Chengb783fa32007-07-19 01:14:50 +00001211def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001212 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001213 [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001214def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001215 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001216 [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng1d5832e2008-01-11 07:37:44 +00001217
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001218let isTwoAddress = 1 in {
1219def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
Evan Chengb783fa32007-07-19 01:14:50 +00001220 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001221 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6227d462007-07-23 03:07:27 +00001222 [(set VR128:$dst,
1223 (int_x86_sse2_cvtsi642sd VR128:$src1,
1224 GR64:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001225def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +00001226 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001227 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6227d462007-07-23 03:07:27 +00001228 [(set VR128:$dst,
1229 (int_x86_sse2_cvtsi642sd VR128:$src1,
1230 (loadi64 addr:$src2)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001231} // isTwoAddress
1232
1233// Signed i64 -> f32
Evan Chengb783fa32007-07-19 01:14:50 +00001234def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001235 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001236 [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001237def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001238 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001239 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng1d5832e2008-01-11 07:37:44 +00001240
1241let isTwoAddress = 1 in {
1242 def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg,
1243 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1244 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1245 [(set VR128:$dst,
1246 (int_x86_sse_cvtsi642ss VR128:$src1,
1247 GR64:$src2))]>;
1248 def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem,
1249 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1250 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1251 [(set VR128:$dst,
1252 (int_x86_sse_cvtsi642ss VR128:$src1,
1253 (loadi64 addr:$src2)))]>;
1254}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001255
1256// f32 -> signed i64
Evan Chengb783fa32007-07-19 01:14:50 +00001257def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001258 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001259 [(set GR64:$dst,
1260 (int_x86_sse_cvtss2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001261def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001262 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001263 [(set GR64:$dst, (int_x86_sse_cvtss2si64
1264 (load addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001265def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001266 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001267 [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001268def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001269 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001270 [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001271def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001272 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001273 [(set GR64:$dst,
1274 (int_x86_sse_cvttss2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001275def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001276 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001277 [(set GR64:$dst,
1278 (int_x86_sse_cvttss2si64 (load addr:$src)))]>;
1279
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001280//===----------------------------------------------------------------------===//
1281// Alias Instructions
1282//===----------------------------------------------------------------------===//
1283
Dan Gohman027cd112007-09-17 14:55:08 +00001284// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
1285// equivalent due to implicit zero-extending, and it sometimes has a smaller
1286// encoding.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001287// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
1288// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
1289// when we have a better way to specify isel priority.
Bill Wendling12e97212008-05-30 06:47:04 +00001290let Defs = [EFLAGS], AddedComplexity = 1,
1291 isReMaterializable = 1, isAsCheapAsAMove = 1 in
Dan Gohman9203ab42008-07-30 18:09:17 +00001292def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins),
1293 "xor{l}\t${dst:subreg32}, ${dst:subreg32}",
1294 [(set GR64:$dst, 0)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001295
1296// Materialize i64 constant where top 32-bits are zero.
Evan Chengbd0ca9c2009-02-05 08:42:55 +00001297let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +00001298def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001299 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001300 [(set GR64:$dst, i64immZExt32:$src)]>;
1301
Anton Korobeynikov4fbf00b2008-05-04 21:36:32 +00001302//===----------------------------------------------------------------------===//
1303// Thread Local Storage Instructions
1304//===----------------------------------------------------------------------===//
1305
Rafael Espindola267934e2009-04-21 08:22:09 +00001306let hasSideEffects = 1, Defs = [RDI] in
Rafael Espindolaaf759ab2009-04-17 14:35:58 +00001307def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
1308 ".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64",
1309 [(X86tlsaddr tglobaltlsaddr:$sym)]>,
1310 Requires<[In64BitMode]>;
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001311
sampo9cc09a32009-01-26 01:24:32 +00001312let AddedComplexity = 5 in
1313def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1314 "movq\t%gs:$src, $dst",
1315 [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
1316
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001317//===----------------------------------------------------------------------===//
1318// Atomic Instructions
1319//===----------------------------------------------------------------------===//
1320
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001321let Defs = [RAX, EFLAGS], Uses = [RAX] in {
Evan Chengd49dbb82008-04-18 20:55:36 +00001322def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
Bill Wendling6f189e22008-08-19 23:09:18 +00001323 "lock\n\tcmpxchgq\t$swap,$ptr",
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001324 [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
1325}
1326
Dan Gohmana41a1c092008-08-06 15:52:50 +00001327let Constraints = "$val = $dst" in {
1328let Defs = [EFLAGS] in
Evan Chengd49dbb82008-04-18 20:55:36 +00001329def LXADD64 : RI<0xC1, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Bill Wendling6f189e22008-08-19 23:09:18 +00001330 "lock\n\txadd\t$val, $ptr",
Mon P Wang6bde9ec2008-06-25 08:15:39 +00001331 [(set GR64:$dst, (atomic_load_add_64 addr:$ptr, GR64:$val))]>,
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001332 TB, LOCK;
Evan Chenga1e80602008-04-19 02:05:42 +00001333def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Bill Wendling6f189e22008-08-19 23:09:18 +00001334 "xchg\t$val, $ptr",
Evan Chenga1e80602008-04-19 02:05:42 +00001335 [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001336}
1337
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001338// Atomic exchange, and, or, xor
1339let Constraints = "$val = $dst", Defs = [EFLAGS],
1340 usesCustomDAGSchedInserter = 1 in {
1341def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001342 "#ATOMAND64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001343 [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001344def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001345 "#ATOMOR64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001346 [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001347def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001348 "#ATOMXOR64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001349 [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001350def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001351 "#ATOMNAND64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001352 [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001353def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001354 "#ATOMMIN64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001355 [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001356def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001357 "#ATOMMAX64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001358 [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001359def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001360 "#ATOMUMIN64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001361 [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001362def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001363 "#ATOMUMAX64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001364 [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001365}
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001366
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001367//===----------------------------------------------------------------------===//
1368// Non-Instruction Patterns
1369//===----------------------------------------------------------------------===//
1370
Bill Wendlingfef06052008-09-16 21:48:12 +00001371// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001372def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1373 (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
1374def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1375 (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
1376def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1377 (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
1378def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1379 (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
1380
1381def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1382 (MOV64mi32 addr:$dst, tconstpool:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001383 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001384def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1385 (MOV64mi32 addr:$dst, tjumptable:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001386 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001387def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1388 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001389 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001390def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1391 (MOV64mi32 addr:$dst, texternalsym:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001392 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001393
1394// Calls
1395// Direct PC relative function call for small code model. 32-bit displacement
1396// sign extended to 64-bit.
1397def : Pat<(X86call (i64 tglobaladdr:$dst)),
1398 (CALL64pcrel32 tglobaladdr:$dst)>;
1399def : Pat<(X86call (i64 texternalsym:$dst)),
1400 (CALL64pcrel32 texternalsym:$dst)>;
1401
1402def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1403 (CALL64pcrel32 tglobaladdr:$dst)>;
1404def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1405 (CALL64pcrel32 texternalsym:$dst)>;
1406
1407def : Pat<(X86tailcall GR64:$dst),
1408 (CALL64r GR64:$dst)>;
1409
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +00001410
1411// tailcall stuff
1412def : Pat<(X86tailcall GR32:$dst),
1413 (TAILCALL)>;
1414def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1415 (TAILCALL)>;
1416def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1417 (TAILCALL)>;
1418
1419def : Pat<(X86tcret GR64:$dst, imm:$off),
1420 (TCRETURNri64 GR64:$dst, imm:$off)>;
1421
1422def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1423 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1424
1425def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1426 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1427
Dan Gohmanec596042007-09-17 14:35:24 +00001428// Comparisons.
1429
1430// TEST R,R is smaller than CMP R,0
Evan Cheng621216e2007-09-29 00:00:36 +00001431def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)),
Dan Gohmanec596042007-09-17 14:35:24 +00001432 (TEST64rr GR64:$src1, GR64:$src1)>;
1433
Dan Gohman0a3c5222009-01-07 01:00:24 +00001434// Conditional moves with folded loads with operands swapped and conditions
1435// inverted.
1436def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
1437 (CMOVAE64rm GR64:$src2, addr:$src1)>;
1438def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
1439 (CMOVB64rm GR64:$src2, addr:$src1)>;
1440def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
1441 (CMOVNE64rm GR64:$src2, addr:$src1)>;
1442def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
1443 (CMOVE64rm GR64:$src2, addr:$src1)>;
1444def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
1445 (CMOVA64rm GR64:$src2, addr:$src1)>;
1446def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
1447 (CMOVBE64rm GR64:$src2, addr:$src1)>;
1448def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
1449 (CMOVGE64rm GR64:$src2, addr:$src1)>;
1450def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
1451 (CMOVL64rm GR64:$src2, addr:$src1)>;
1452def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
1453 (CMOVG64rm GR64:$src2, addr:$src1)>;
1454def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
1455 (CMOVLE64rm GR64:$src2, addr:$src1)>;
1456def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
1457 (CMOVNP64rm GR64:$src2, addr:$src1)>;
1458def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
1459 (CMOVP64rm GR64:$src2, addr:$src1)>;
1460def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
1461 (CMOVNS64rm GR64:$src2, addr:$src1)>;
1462def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
1463 (CMOVS64rm GR64:$src2, addr:$src1)>;
1464def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
1465 (CMOVNO64rm GR64:$src2, addr:$src1)>;
1466def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
1467 (CMOVO64rm GR64:$src2, addr:$src1)>;
Christopher Lambb371e032008-03-13 05:47:01 +00001468
Duncan Sands082524c2008-01-23 20:39:46 +00001469// zextload bool -> zextload byte
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001470def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1471
1472// extload
Dan Gohmanab460da2008-08-27 17:33:15 +00001473// When extloading from 16-bit and smaller memory locations into 64-bit registers,
1474// use zero-extending loads so that the entire 64-bit register is defined, avoiding
1475// partial-register updates.
1476def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1477def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
1478def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1479// For other extloads, use subregs, since the high contents of the register are
1480// defined after an extload.
Dan Gohmandd612bb2008-08-20 21:27:32 +00001481def : Pat<(extloadi64i32 addr:$src),
1482 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
1483 x86_subreg_32bit)>;
1484def : Pat<(extloadi16i1 addr:$src),
1485 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1486 x86_subreg_8bit)>,
1487 Requires<[In64BitMode]>;
1488def : Pat<(extloadi16i8 addr:$src),
1489 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1490 x86_subreg_8bit)>,
1491 Requires<[In64BitMode]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001492
Dan Gohmandd612bb2008-08-20 21:27:32 +00001493// anyext
1494def : Pat<(i64 (anyext GR8:$src)),
1495 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
1496def : Pat<(i64 (anyext GR16:$src)),
1497 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
Christopher Lamb76d72da2008-03-16 03:12:01 +00001498def : Pat<(i64 (anyext GR32:$src)),
1499 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001500def : Pat<(i16 (anyext GR8:$src)),
1501 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1502 Requires<[In64BitMode]>;
1503def : Pat<(i32 (anyext GR8:$src)),
1504 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1505 Requires<[In64BitMode]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001506
1507//===----------------------------------------------------------------------===//
1508// Some peepholes
1509//===----------------------------------------------------------------------===//
1510
Dan Gohman5a5e6e92008-10-17 01:33:43 +00001511// Odd encoding trick: -128 fits into an 8-bit immediate field while
1512// +128 doesn't, so in this special case use a sub instead of an add.
1513def : Pat<(add GR64:$src1, 128),
1514 (SUB64ri8 GR64:$src1, -128)>;
1515def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1516 (SUB64mi8 addr:$dst, -128)>;
1517
1518// The same trick applies for 32-bit immediate fields in 64-bit
1519// instructions.
1520def : Pat<(add GR64:$src1, 0x0000000080000000),
1521 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1522def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
1523 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1524
Dan Gohman47a419d2008-08-07 02:54:50 +00001525// r & (2^32-1) ==> movz
Dan Gohman5a5e6e92008-10-17 01:33:43 +00001526def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
Dan Gohman744d4622009-04-13 16:09:41 +00001527 (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
Dan Gohman9203ab42008-07-30 18:09:17 +00001528// r & (2^16-1) ==> movz
1529def : Pat<(and GR64:$src, 0xffff),
1530 (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
1531// r & (2^8-1) ==> movz
1532def : Pat<(and GR64:$src, 0xff),
1533 (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
Dan Gohman9203ab42008-07-30 18:09:17 +00001534// r & (2^8-1) ==> movz
1535def : Pat<(and GR32:$src1, 0xff),
Dan Gohman744d4622009-04-13 16:09:41 +00001536 (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>,
Dan Gohman9203ab42008-07-30 18:09:17 +00001537 Requires<[In64BitMode]>;
1538// r & (2^8-1) ==> movz
1539def : Pat<(and GR16:$src1, 0xff),
1540 (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
1541 Requires<[In64BitMode]>;
Christopher Lambb371e032008-03-13 05:47:01 +00001542
Dan Gohmandd612bb2008-08-20 21:27:32 +00001543// sext_inreg patterns
1544def : Pat<(sext_inreg GR64:$src, i32),
Dan Gohman744d4622009-04-13 16:09:41 +00001545 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001546def : Pat<(sext_inreg GR64:$src, i16),
Dan Gohman744d4622009-04-13 16:09:41 +00001547 (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001548def : Pat<(sext_inreg GR64:$src, i8),
Dan Gohman744d4622009-04-13 16:09:41 +00001549 (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001550def : Pat<(sext_inreg GR32:$src, i8),
Dan Gohman744d4622009-04-13 16:09:41 +00001551 (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
Dan Gohmandd612bb2008-08-20 21:27:32 +00001552 Requires<[In64BitMode]>;
1553def : Pat<(sext_inreg GR16:$src, i8),
1554 (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
1555 Requires<[In64BitMode]>;
1556
1557// trunc patterns
1558def : Pat<(i32 (trunc GR64:$src)),
Dan Gohman744d4622009-04-13 16:09:41 +00001559 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001560def : Pat<(i16 (trunc GR64:$src)),
Dan Gohman744d4622009-04-13 16:09:41 +00001561 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001562def : Pat<(i8 (trunc GR64:$src)),
Dan Gohman744d4622009-04-13 16:09:41 +00001563 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001564def : Pat<(i8 (trunc GR32:$src)),
Dan Gohman744d4622009-04-13 16:09:41 +00001565 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>,
Dan Gohmandd612bb2008-08-20 21:27:32 +00001566 Requires<[In64BitMode]>;
1567def : Pat<(i8 (trunc GR16:$src)),
Dan Gohman744d4622009-04-13 16:09:41 +00001568 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>,
1569 Requires<[In64BitMode]>;
1570
1571// h-register tricks.
1572// For now, be conservative and only the extract if the value is immediately
1573// zero-extended or stored, which are somewhat common cases. This uses a bunch
1574// of code to prevent a register requiring a REX prefix from being allocated in
1575// the same instruction as the h register, as there's currently no way to
1576// describe this requirement to the register allocator.
1577
1578// h-register extract and zero-extend.
1579def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
1580 (SUBREG_TO_REG
1581 (i64 0),
1582 (MOVZX32_NOREXrr8
Dan Gohman4c10fc72009-04-13 21:06:25 +00001583 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_),
Dan Gohman744d4622009-04-13 16:09:41 +00001584 x86_subreg_8bit_hi)),
1585 x86_subreg_32bit)>;
1586def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
1587 (MOVZX32_NOREXrr8
Dan Gohman4c10fc72009-04-13 21:06:25 +00001588 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_),
Dan Gohman744d4622009-04-13 16:09:41 +00001589 x86_subreg_8bit_hi))>,
1590 Requires<[In64BitMode]>;
1591def : Pat<(srl_su GR16:$src, (i8 8)),
1592 (EXTRACT_SUBREG
1593 (MOVZX32_NOREXrr8
Dan Gohman4c10fc72009-04-13 21:06:25 +00001594 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_),
Dan Gohman744d4622009-04-13 16:09:41 +00001595 x86_subreg_8bit_hi)),
1596 x86_subreg_16bit)>,
1597 Requires<[In64BitMode]>;
1598
1599// h-register extract and store.
1600def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
1601 (MOV8mr_NOREX
1602 addr:$dst,
Dan Gohman4c10fc72009-04-13 21:06:25 +00001603 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_),
Dan Gohman744d4622009-04-13 16:09:41 +00001604 x86_subreg_8bit_hi))>;
1605def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
1606 (MOV8mr_NOREX
1607 addr:$dst,
Dan Gohman4c10fc72009-04-13 21:06:25 +00001608 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_),
Dan Gohman744d4622009-04-13 16:09:41 +00001609 x86_subreg_8bit_hi))>,
1610 Requires<[In64BitMode]>;
1611def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
1612 (MOV8mr_NOREX
1613 addr:$dst,
Dan Gohman4c10fc72009-04-13 21:06:25 +00001614 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_),
Dan Gohman744d4622009-04-13 16:09:41 +00001615 x86_subreg_8bit_hi))>,
Dan Gohmandd612bb2008-08-20 21:27:32 +00001616 Requires<[In64BitMode]>;
1617
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001618// (shl x, 1) ==> (add x, x)
1619def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1620
Evan Cheng76a64c72008-08-30 02:03:58 +00001621// (shl x (and y, 63)) ==> (shl x, y)
1622def : Pat<(shl GR64:$src1, (and CL:$amt, 63)),
1623 (SHL64rCL GR64:$src1)>;
1624def : Pat<(store (shl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1625 (SHL64mCL addr:$dst)>;
1626
1627def : Pat<(srl GR64:$src1, (and CL:$amt, 63)),
1628 (SHR64rCL GR64:$src1)>;
1629def : Pat<(store (srl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1630 (SHR64mCL addr:$dst)>;
1631
1632def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
1633 (SAR64rCL GR64:$src1)>;
1634def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1635 (SAR64mCL addr:$dst)>;
1636
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001637// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
1638def : Pat<(or (srl GR64:$src1, CL:$amt),
1639 (shl GR64:$src2, (sub 64, CL:$amt))),
1640 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1641
1642def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
1643 (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1644 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1645
Dan Gohman921581d2008-10-17 01:23:35 +00001646def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))),
1647 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1648 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1649
1650def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1651 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1652 addr:$dst),
1653 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1654
1655def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1656 (SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1657
1658def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
1659 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1660 (SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1661
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001662// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
1663def : Pat<(or (shl GR64:$src1, CL:$amt),
1664 (srl GR64:$src2, (sub 64, CL:$amt))),
1665 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1666
1667def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
1668 (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1669 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1670
Dan Gohman921581d2008-10-17 01:23:35 +00001671def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))),
1672 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1673 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1674
1675def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1676 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1677 addr:$dst),
1678 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1679
1680def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1681 (SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1682
1683def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
1684 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1685 (SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1686
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001687// X86 specific add which produces a flag.
1688def : Pat<(addc GR64:$src1, GR64:$src2),
1689 (ADD64rr GR64:$src1, GR64:$src2)>;
1690def : Pat<(addc GR64:$src1, (load addr:$src2)),
1691 (ADD64rm GR64:$src1, addr:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001692def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
1693 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohmand16fdc02008-12-19 18:25:21 +00001694def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
1695 (ADD64ri32 GR64:$src1, imm:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001696
1697def : Pat<(subc GR64:$src1, GR64:$src2),
1698 (SUB64rr GR64:$src1, GR64:$src2)>;
1699def : Pat<(subc GR64:$src1, (load addr:$src2)),
1700 (SUB64rm GR64:$src1, addr:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001701def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
1702 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohmand16fdc02008-12-19 18:25:21 +00001703def : Pat<(subc GR64:$src1, imm:$src2),
1704 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001705
Bill Wendlingf5399032008-12-12 21:15:41 +00001706//===----------------------------------------------------------------------===//
Dan Gohman99a12192009-03-04 19:44:21 +00001707// EFLAGS-defining Patterns
Bill Wendlingf5399032008-12-12 21:15:41 +00001708//===----------------------------------------------------------------------===//
1709
Dan Gohman99a12192009-03-04 19:44:21 +00001710// Register-Register Addition with EFLAGS result
1711def : Pat<(parallel (X86add_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001712 (implicit EFLAGS)),
1713 (ADD64rr GR64:$src1, GR64:$src2)>;
1714
Dan Gohman99a12192009-03-04 19:44:21 +00001715// Register-Integer Addition with EFLAGS result
1716def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001717 (implicit EFLAGS)),
1718 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001719def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001720 (implicit EFLAGS)),
1721 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001722
Dan Gohman99a12192009-03-04 19:44:21 +00001723// Register-Memory Addition with EFLAGS result
1724def : Pat<(parallel (X86add_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001725 (implicit EFLAGS)),
1726 (ADD64rm GR64:$src1, addr:$src2)>;
1727
Dan Gohman99a12192009-03-04 19:44:21 +00001728// Memory-Register Addition with EFLAGS result
1729def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001730 addr:$dst),
1731 (implicit EFLAGS)),
1732 (ADD64mr addr:$dst, GR64:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001733def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001734 addr:$dst),
1735 (implicit EFLAGS)),
1736 (ADD64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001737def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001738 addr:$dst),
1739 (implicit EFLAGS)),
1740 (ADD64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001741
Dan Gohman99a12192009-03-04 19:44:21 +00001742// Register-Register Subtraction with EFLAGS result
1743def : Pat<(parallel (X86sub_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001744 (implicit EFLAGS)),
1745 (SUB64rr GR64:$src1, GR64:$src2)>;
1746
Dan Gohman99a12192009-03-04 19:44:21 +00001747// Register-Memory Subtraction with EFLAGS result
1748def : Pat<(parallel (X86sub_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001749 (implicit EFLAGS)),
1750 (SUB64rm GR64:$src1, addr:$src2)>;
1751
Dan Gohman99a12192009-03-04 19:44:21 +00001752// Register-Integer Subtraction with EFLAGS result
1753def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001754 (implicit EFLAGS)),
1755 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001756def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001757 (implicit EFLAGS)),
1758 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001759
Dan Gohman99a12192009-03-04 19:44:21 +00001760// Memory-Register Subtraction with EFLAGS result
1761def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001762 addr:$dst),
1763 (implicit EFLAGS)),
1764 (SUB64mr addr:$dst, GR64:$src2)>;
1765
Dan Gohman99a12192009-03-04 19:44:21 +00001766// Memory-Integer Subtraction with EFLAGS result
1767def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001768 addr:$dst),
1769 (implicit EFLAGS)),
1770 (SUB64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001771def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001772 addr:$dst),
1773 (implicit EFLAGS)),
1774 (SUB64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001775
Dan Gohman99a12192009-03-04 19:44:21 +00001776// Register-Register Signed Integer Multiplication with EFLAGS result
1777def : Pat<(parallel (X86smul_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001778 (implicit EFLAGS)),
1779 (IMUL64rr GR64:$src1, GR64:$src2)>;
1780
Dan Gohman99a12192009-03-04 19:44:21 +00001781// Register-Memory Signed Integer Multiplication with EFLAGS result
1782def : Pat<(parallel (X86smul_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001783 (implicit EFLAGS)),
1784 (IMUL64rm GR64:$src1, addr:$src2)>;
1785
Dan Gohman99a12192009-03-04 19:44:21 +00001786// Register-Integer Signed Integer Multiplication with EFLAGS result
1787def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001788 (implicit EFLAGS)),
1789 (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001790def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001791 (implicit EFLAGS)),
1792 (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001793
Dan Gohman99a12192009-03-04 19:44:21 +00001794// Memory-Integer Signed Integer Multiplication with EFLAGS result
1795def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001796 (implicit EFLAGS)),
1797 (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001798def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001799 (implicit EFLAGS)),
1800 (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001801
Dan Gohman99a12192009-03-04 19:44:21 +00001802// INC and DEC with EFLAGS result. Note that these do not set CF.
Dan Gohmaneebcac72009-03-05 21:32:23 +00001803def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)),
1804 (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1805def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst),
1806 (implicit EFLAGS)),
1807 (INC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1808def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)),
1809 (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1810def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst),
1811 (implicit EFLAGS)),
1812 (DEC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1813
1814def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)),
1815 (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1816def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst),
1817 (implicit EFLAGS)),
1818 (INC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1819def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)),
1820 (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1821def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst),
1822 (implicit EFLAGS)),
1823 (DEC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1824
Dan Gohman99a12192009-03-04 19:44:21 +00001825def : Pat<(parallel (X86inc_flag GR64:$src), (implicit EFLAGS)),
1826 (INC64r GR64:$src)>;
1827def : Pat<(parallel (store (i64 (X86inc_flag (loadi64 addr:$dst))), addr:$dst),
1828 (implicit EFLAGS)),
1829 (INC64m addr:$dst)>;
1830def : Pat<(parallel (X86dec_flag GR64:$src), (implicit EFLAGS)),
1831 (DEC64r GR64:$src)>;
1832def : Pat<(parallel (store (i64 (X86dec_flag (loadi64 addr:$dst))), addr:$dst),
1833 (implicit EFLAGS)),
1834 (DEC64m addr:$dst)>;
1835
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001836//===----------------------------------------------------------------------===//
1837// X86-64 SSE Instructions
1838//===----------------------------------------------------------------------===//
1839
1840// Move instructions...
1841
Evan Chengb783fa32007-07-19 01:14:50 +00001842def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001843 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001844 [(set VR128:$dst,
1845 (v2i64 (scalar_to_vector GR64:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001846def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001847 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001848 [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
1849 (iPTR 0)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001850
Evan Chengb783fa32007-07-19 01:14:50 +00001851def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001852 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001853 [(set FR64:$dst, (bitconvert GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001854def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Evan Cheng69ca4da2008-08-25 04:11:42 +00001855 "movq\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001856 [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
1857
Evan Chengb783fa32007-07-19 01:14:50 +00001858def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001859 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001860 [(set GR64:$dst, (bitconvert FR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001861def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
Evan Cheng69ca4da2008-08-25 04:11:42 +00001862 "movq\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001863 [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
Nate Begemanb2975562008-02-03 07:18:54 +00001864
1865//===----------------------------------------------------------------------===//
1866// X86-64 SSE4.1 Instructions
1867//===----------------------------------------------------------------------===//
1868
Nate Begeman4294c1f2008-02-12 22:51:28 +00001869/// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
1870multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
Nate Begeman0050ab52008-10-29 23:07:17 +00001871 def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001872 (ins VR128:$src1, i32i8imm:$src2),
1873 !strconcat(OpcodeStr,
1874 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1875 [(set GR64:$dst,
1876 (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
Evan Cheng78d00612008-03-14 07:39:27 +00001877 def mr : SS4AIi8<opc, MRMDestMem, (outs),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001878 (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
1879 !strconcat(OpcodeStr,
1880 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1881 [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
1882 addr:$dst)]>, OpSize, REX_W;
1883}
1884
1885defm PEXTRQ : SS41I_extract64<0x16, "pextrq">;
1886
1887let isTwoAddress = 1 in {
1888 multiclass SS41I_insert64<bits<8> opc, string OpcodeStr> {
Evan Cheng78d00612008-03-14 07:39:27 +00001889 def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001890 (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
1891 !strconcat(OpcodeStr,
1892 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1893 [(set VR128:$dst,
1894 (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
1895 OpSize, REX_W;
Evan Cheng78d00612008-03-14 07:39:27 +00001896 def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001897 (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
1898 !strconcat(OpcodeStr,
1899 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1900 [(set VR128:$dst,
1901 (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
1902 imm:$src3)))]>, OpSize, REX_W;
1903 }
1904}
1905
1906defm PINSRQ : SS41I_insert64<0x22, "pinsrq">;