blob: a6c0800c80c2adedd45b919d6c41589a3b755b05 [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> {
26 let PrintMethod = "printi64mem";
27 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",
39 [add, mul, shl, or, frameindex, X86Wrapper],
40 []>;
41
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 {
Evan Cheng75952172009-03-04 06:48:53 +0000112 def CALL64pcrel32 : I<0xE8, RawFrm,
113 (outs), (ins i64i32imm:$dst, variable_ops),
114 "call\t${dst:call}", [(X86call imm:$dst)]>,
115 Requires<[In64BitMode]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000116 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
Dan Gohman91888f02007-07-31 20:11:57 +0000117 "call\t{*}$dst", [(X86call GR64:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000118 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
Dan Gohmanea4faba2008-05-29 21:50:34 +0000119 "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000120 }
121
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000122
123
124let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000125def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset,
126 variable_ops),
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000127 "#TC_RETURN $dst $offset",
128 []>;
129
130let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000131def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
132 variable_ops),
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000133 "#TC_RETURN $dst $offset",
134 []>;
135
136
137let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
Evan Chengbd780d22009-02-10 21:39:44 +0000138 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst),
139 "jmp{q}\t{*}$dst # TAILCALL",
140 []>;
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +0000141
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000142// Branches
Owen Andersonf8053082007-11-12 07:39:39 +0000143let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
Dan Gohman91888f02007-07-31 20:11:57 +0000144 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000145 [(brind GR64:$dst)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000146 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000147 [(brind (loadi64 addr:$dst))]>;
148}
149
150//===----------------------------------------------------------------------===//
Anton Korobeynikov1ec04ee2008-09-08 21:12:47 +0000151// EH Pseudo Instructions
152//
153let isTerminator = 1, isReturn = 1, isBarrier = 1,
154 hasCtrlDep = 1 in {
155def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
156 "ret\t#eh_return, addr: $addr",
157 [(X86ehret GR64:$addr)]>;
158
159}
160
161//===----------------------------------------------------------------------===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000162// Miscellaneous Instructions...
163//
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000164let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000165def LEAVE64 : I<0xC9, RawFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000166 (outs), (ins), "leave", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000167let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
168let mayLoad = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000169def POP64r : I<0x58, AddRegFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000170 (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000171let mayStore = 1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000172def PUSH64r : I<0x50, AddRegFrm,
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000173 (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
174}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000175
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000176let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
Evan Chengf1341312007-09-26 21:28:00 +0000177def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000178let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
Evan Chengf1341312007-09-26 21:28:00 +0000179def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
Evan Chengd8434332007-09-26 01:29:06 +0000180
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000181def LEA64_32r : I<0x8D, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000182 (outs GR32:$dst), (ins lea64_32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000183 "lea{l}\t{$src|$dst}, {$dst|$src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000184 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
185
Evan Cheng1ea8e6b2008-03-27 01:41:09 +0000186let isReMaterializable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000187def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000188 "lea{q}\t{$src|$dst}, {$dst|$src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000189 [(set GR64:$dst, lea64addr:$src)]>;
190
191let isTwoAddress = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000192def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000193 "bswap{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000194 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000195
Evan Cheng48679f42007-12-14 02:13:44 +0000196// Bit scan instructions.
197let Defs = [EFLAGS] in {
Evan Cheng4e33de92007-12-14 18:49:43 +0000198def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000199 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000200 [(set GR64:$dst, (X86bsf GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000201def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000202 "bsf{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000203 [(set GR64:$dst, (X86bsf (loadi64 addr:$src))),
204 (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000205
Evan Cheng4e33de92007-12-14 18:49:43 +0000206def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000207 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000208 [(set GR64:$dst, (X86bsr GR64:$src)), (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000209def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohmancdb54c62007-12-14 15:10:00 +0000210 "bsr{q}\t{$src, $dst|$dst, $src}",
Evan Cheng9a8ffd52007-12-14 18:25:34 +0000211 [(set GR64:$dst, (X86bsr (loadi64 addr:$src))),
212 (implicit EFLAGS)]>, TB;
Evan Cheng48679f42007-12-14 02:13:44 +0000213} // Defs = [EFLAGS]
214
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000215// Repeat string ops
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000216let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in
Evan Chengb783fa32007-07-19 01:14:50 +0000217def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000218 [(X86rep_movs i64)]>, REP;
219let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in
Evan Chengb783fa32007-07-19 01:14:50 +0000220def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000221 [(X86rep_stos i64)]>, REP;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000222
223//===----------------------------------------------------------------------===//
224// Move Instructions...
225//
226
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000227let neverHasSideEffects = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000228def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000229 "mov{q}\t{$src, $dst|$dst, $src}", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000230
Evan Chengd2b9d302008-06-25 01:16:38 +0000231let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000232def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000233 "movabs{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000234 [(set GR64:$dst, imm:$src)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000235def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000236 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000237 [(set GR64:$dst, i64immSExt32:$src)]>;
Dan Gohman8aef09b2007-09-07 21:32:51 +0000238}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000239
Dan Gohman5574cc72008-12-03 18:15:48 +0000240let canFoldAsLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000241def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000242 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000243 [(set GR64:$dst, (load addr:$src))]>;
244
Evan Chengb783fa32007-07-19 01:14:50 +0000245def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000246 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000247 [(store GR64:$src, addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000248def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000249 "mov{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000250 [(store i64immSExt32:$src, addr:$dst)]>;
251
252// Sign/Zero extenders
253
Evan Chengb783fa32007-07-19 01:14:50 +0000254def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000255 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000256 [(set GR64:$dst, (sext GR8:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000257def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000258 "movs{bq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000259 [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000260def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000261 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000262 [(set GR64:$dst, (sext GR16:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000263def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000264 "movs{wq|x}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000265 [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000266def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000267 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000268 [(set GR64:$dst, (sext GR32:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000269def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000270 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000271 [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
272
Dan Gohman9203ab42008-07-30 18:09:17 +0000273// Use movzbl instead of movzbq when the destination is a register; it's
274// equivalent due to implicit zero-extending, and it has a smaller encoding.
275def MOVZX64rr8 : I<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
276 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
277 [(set GR64:$dst, (zext GR8:$src))]>, TB;
278def MOVZX64rm8 : I<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
279 "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
280 [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
281// Use movzwl instead of movzwq when the destination is a register; it's
282// equivalent due to implicit zero-extending, and it has a smaller encoding.
283def MOVZX64rr16: I<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
284 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
285 [(set GR64:$dst, (zext GR16:$src))]>, TB;
286def MOVZX64rm16: I<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
287 "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
288 [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000289
Dan Gohman47a419d2008-08-07 02:54:50 +0000290// There's no movzlq instruction, but movl can be used for this purpose, using
291// implicit zero-extension. We need this because the seeming alternative for
292// implementing zext from 32 to 64, an EXTRACT_SUBREG/SUBREG_TO_REG pair, isn't
293// safe because both instructions could be optimized away in the
294// register-to-register case, leaving nothing behind to do the zero extension.
295def MOVZX64rr32 : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
296 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
297 [(set GR64:$dst, (zext GR32:$src))]>;
298def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
299 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
300 [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
301
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000302let neverHasSideEffects = 1 in {
303 let Defs = [RAX], Uses = [EAX] in
304 def CDQE : RI<0x98, RawFrm, (outs), (ins),
305 "{cltq|cdqe}", []>; // RAX = signext(EAX)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000306
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000307 let Defs = [RAX,RDX], Uses = [RAX] in
308 def CQO : RI<0x99, RawFrm, (outs), (ins),
309 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
310}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000311
312//===----------------------------------------------------------------------===//
313// Arithmetic Instructions...
314//
315
Evan Cheng55687072007-09-14 21:48:26 +0000316let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000317let isTwoAddress = 1 in {
318let isConvertibleToThreeAddress = 1 in {
319let isCommutable = 1 in
Bill Wendlingae034ed2008-12-12 00:56:36 +0000320// Register-Register Addition
321def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
322 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000323 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
Bill Wendlingae034ed2008-12-12 00:56:36 +0000324 (implicit EFLAGS)]>;
325
326// Register-Integer Addition
Bill Wendlingae034ed2008-12-12 00:56:36 +0000327def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
328 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000329 [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)),
330 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000331def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
332 "add{q}\t{$src2, $dst|$dst, $src2}",
333 [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)),
334 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000335} // isConvertibleToThreeAddress
336
Bill Wendlingae034ed2008-12-12 00:56:36 +0000337// Register-Memory Addition
338def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
339 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000340 [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))),
Bill Wendlingae034ed2008-12-12 00:56:36 +0000341 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000342} // isTwoAddress
343
Bill Wendlingae034ed2008-12-12 00:56:36 +0000344// Memory-Register Addition
Evan Chengb783fa32007-07-19 01:14:50 +0000345def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000346 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000347 [(store (add (load addr:$dst), GR64:$src2), addr:$dst),
348 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000349def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000350 "add{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000351 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst),
352 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000353def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
354 "add{q}\t{$src2, $dst|$dst, $src2}",
355 [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst),
356 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000357
Evan Cheng259471d2007-10-05 17:59:57 +0000358let Uses = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000359let isTwoAddress = 1 in {
360let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000361def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000362 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000363 [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000364
Evan Chengb783fa32007-07-19 01:14:50 +0000365def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000366 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000367 [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000368
Evan Chengb783fa32007-07-19 01:14:50 +0000369def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000370 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000371 [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000372def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
373 "adc{q}\t{$src2, $dst|$dst, $src2}",
374 [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000375} // isTwoAddress
376
Evan Chengb783fa32007-07-19 01:14:50 +0000377def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000378 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingc0ca7f32008-12-01 23:44:08 +0000379 [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000380def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000381 "adc{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling0c52d0a2008-12-02 00:07:05 +0000382 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000383def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
384 "adc{q}\t{$src2, $dst|$dst, $src2}",
385 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Evan Cheng259471d2007-10-05 17:59:57 +0000386} // Uses = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000387
388let isTwoAddress = 1 in {
Bill Wendlingae034ed2008-12-12 00:56:36 +0000389// Register-Register Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000390def SUB64rr : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000391 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000392 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2)),
393 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000394
395// Register-Memory Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000396def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000397 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000398 [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2))),
399 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000400
401// Register-Integer Subtraction
Bill Wendlingae034ed2008-12-12 00:56:36 +0000402def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
403 (ins GR64:$src1, i64i8imm:$src2),
404 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000405 [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2)),
406 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000407def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
408 (ins GR64:$src1, i64i32imm:$src2),
409 "sub{q}\t{$src2, $dst|$dst, $src2}",
410 [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2)),
411 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000412} // isTwoAddress
413
Bill Wendlingae034ed2008-12-12 00:56:36 +0000414// Memory-Register Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000415def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, 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 [(store (sub (load addr:$dst), GR64:$src2), addr:$dst),
418 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000419
420// Memory-Integer Subtraction
Evan Chengb783fa32007-07-19 01:14:50 +0000421def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000422 "sub{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingae034ed2008-12-12 00:56:36 +0000423 [(store (sub (load addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +0000424 addr:$dst),
425 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000426def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
427 "sub{q}\t{$src2, $dst|$dst, $src2}",
428 [(store (sub (load addr:$dst), i64immSExt32:$src2),
429 addr:$dst),
430 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000431
Evan Cheng259471d2007-10-05 17:59:57 +0000432let Uses = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000433let isTwoAddress = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000434def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000435 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000436 [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
437
Evan Chengb783fa32007-07-19 01:14:50 +0000438def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000439 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000440 [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
441
Evan Chengb783fa32007-07-19 01:14:50 +0000442def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000443 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000444 [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000445def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
446 "sbb{q}\t{$src2, $dst|$dst, $src2}",
447 [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000448} // isTwoAddress
449
Evan Chengb783fa32007-07-19 01:14:50 +0000450def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000451 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000452 [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000453def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000454 "sbb{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000455 [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000456def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
457 "sbb{q}\t{$src2, $dst|$dst, $src2}",
458 [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
Evan Cheng259471d2007-10-05 17:59:57 +0000459} // Uses = [EFLAGS]
Evan Cheng55687072007-09-14 21:48:26 +0000460} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000461
462// Unsigned multiplication
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000463let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000464def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000465 "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000466let mayLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000467def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000468 "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000469
470// Signed multiplication
Evan Chengb783fa32007-07-19 01:14:50 +0000471def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000472 "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000473let mayLoad = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000474def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000475 "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
476}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000477
Evan Cheng55687072007-09-14 21:48:26 +0000478let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000479let isTwoAddress = 1 in {
480let isCommutable = 1 in
Bill Wendlingf5399032008-12-12 21:15:41 +0000481// Register-Register Signed Integer Multiplication
Bill Wendlingae034ed2008-12-12 00:56:36 +0000482def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
483 (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000484 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000485 [(set GR64:$dst, (mul GR64:$src1, GR64:$src2)),
486 (implicit EFLAGS)]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000487
Bill Wendlingf5399032008-12-12 21:15:41 +0000488// Register-Memory Signed Integer Multiplication
Bill Wendlingae034ed2008-12-12 00:56:36 +0000489def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
490 (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000491 "imul{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000492 [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2))),
493 (implicit EFLAGS)]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000494} // isTwoAddress
495
496// Suprisingly enough, these are not two address instructions!
Bill Wendlingae034ed2008-12-12 00:56:36 +0000497
Bill Wendlingf5399032008-12-12 21:15:41 +0000498// Register-Integer Signed Integer Multiplication
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000499def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
Evan Chengb783fa32007-07-19 01:14:50 +0000500 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000501 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingf5399032008-12-12 21:15:41 +0000502 [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2)),
503 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000504def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
505 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
506 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
507 [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2)),
508 (implicit EFLAGS)]>;
Bill Wendlingae034ed2008-12-12 00:56:36 +0000509
Bill Wendlingf5399032008-12-12 21:15:41 +0000510// Memory-Integer Signed Integer Multiplication
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000511def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
Evan Chengb783fa32007-07-19 01:14:50 +0000512 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000513 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
Bill Wendlingae034ed2008-12-12 00:56:36 +0000514 [(set GR64:$dst, (mul (load addr:$src1),
Bill Wendlingf5399032008-12-12 21:15:41 +0000515 i64immSExt8:$src2)),
516 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000517def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
518 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
519 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
520 [(set GR64:$dst, (mul (load addr:$src1),
521 i64immSExt32:$src2)),
522 (implicit EFLAGS)]>;
Evan Cheng55687072007-09-14 21:48:26 +0000523} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000524
525// Unsigned division / remainder
Evan Cheng55687072007-09-14 21:48:26 +0000526let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000527def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000528 "div{q}\t$src", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000529// Signed division / remainder
Evan Chengb783fa32007-07-19 01:14:50 +0000530def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000531 "idiv{q}\t$src", []>;
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000532let mayLoad = 1 in {
533def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
534 "div{q}\t$src", []>;
Evan Chengb783fa32007-07-19 01:14:50 +0000535def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000536 "idiv{q}\t$src", []>;
537}
Chris Lattnerc90ee9c2008-01-10 07:59:24 +0000538}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000539
540// Unary instructions
Evan Cheng55687072007-09-14 21:48:26 +0000541let Defs = [EFLAGS], CodeSize = 2 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000542let isTwoAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000543def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000544 [(set GR64:$dst, (ineg GR64:$src)),
545 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000546def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000547 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
548 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000549
550let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000551def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000552 [(set GR64:$dst, (add GR64:$src, 1)),
553 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000554def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000555 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
556 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000557
558let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
Dan Gohman91888f02007-07-31 20:11:57 +0000559def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000560 [(set GR64:$dst, (add GR64:$src, -1)),
561 (implicit EFLAGS)]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000562def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000563 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
564 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000565
566// In 64-bit mode, single byte INC and DEC cannot be encoded.
567let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
568// Can transform into LEA.
Dan Gohman91888f02007-07-31 20:11:57 +0000569def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src), "inc{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000570 [(set GR16:$dst, (add GR16:$src, 1)),
571 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000572 OpSize, Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000573def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src), "inc{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000574 [(set GR32:$dst, (add GR32:$src, 1)),
575 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000576 Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000577def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src), "dec{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000578 [(set GR16:$dst, (add GR16:$src, -1)),
579 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000580 OpSize, Requires<[In64BitMode]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000581def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000582 [(set GR32:$dst, (add GR32:$src, -1)),
583 (implicit EFLAGS)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000584 Requires<[In64BitMode]>;
585} // isConvertibleToThreeAddress
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000586
587// These are duplicates of their 32-bit counterparts. Only needed so X86 knows
588// how to unfold them.
589let isTwoAddress = 0, CodeSize = 2 in {
590 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000591 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
592 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000593 OpSize, Requires<[In64BitMode]>;
594 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000595 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
596 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000597 Requires<[In64BitMode]>;
598 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000599 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
600 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000601 OpSize, Requires<[In64BitMode]>;
602 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000603 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
604 (implicit EFLAGS)]>,
Evan Cheng4a7e72f2007-10-19 21:23:22 +0000605 Requires<[In64BitMode]>;
606}
Evan Cheng55687072007-09-14 21:48:26 +0000607} // Defs = [EFLAGS], CodeSize
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000608
609
Evan Cheng55687072007-09-14 21:48:26 +0000610let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000611// Shift instructions
612let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000613let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000614def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000615 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000616 [(set GR64:$dst, (shl GR64:$src, CL))]>;
Evan Chenga98f6272007-10-05 18:20:36 +0000617let isConvertibleToThreeAddress = 1 in // Can transform into LEA.
Evan Chengb783fa32007-07-19 01:14:50 +0000618def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000619 "shl{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000620 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
Chris Lattnerf4005a82008-01-11 18:00:50 +0000621// NOTE: We don't use shifts of a register by one, because 'add reg,reg' is
622// cheaper.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000623} // isTwoAddress
624
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000625let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000626def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000627 "shl{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000628 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000629def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000630 "shl{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000631 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000632def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000633 "shl{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000634 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
635
636let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000637let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000638def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000639 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000640 [(set GR64:$dst, (srl GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000641def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000642 "shr{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000643 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000644def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000645 "shr{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000646 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
647} // isTwoAddress
648
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000649let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000650def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000651 "shr{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000652 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000653def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000654 "shr{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000655 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000656def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000657 "shr{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000658 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
659
660let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000661let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000662def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000663 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000664 [(set GR64:$dst, (sra GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000665def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000666 "sar{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000667 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000668def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000669 "sar{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000670 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
671} // isTwoAddress
672
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000673let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000674def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000675 "sar{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000676 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000677def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000678 "sar{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000679 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000680def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000681 "sar{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000682 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
683
684// Rotate instructions
685let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000686let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000687def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000688 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000689 [(set GR64:$dst, (rotl GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000690def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000691 "rol{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000692 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000693def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000694 "rol{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000695 [(set GR64:$dst, (rotl 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 ROL64mCL : I<0xD3, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000700 "rol{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000701 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000702def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000703 "rol{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000704 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000705def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000706 "rol{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000707 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
708
709let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000710let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000711def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000712 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000713 [(set GR64:$dst, (rotr GR64:$src, CL))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000714def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000715 "ror{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000716 [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000717def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
Dan Gohman91888f02007-07-31 20:11:57 +0000718 "ror{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000719 [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
720} // isTwoAddress
721
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000722let Uses = [CL] in
Evan Chengb783fa32007-07-19 01:14:50 +0000723def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000724 "ror{q}\t{%cl, $dst|$dst, %CL}",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000725 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000726def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000727 "ror{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000728 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000729def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
Dan Gohman91888f02007-07-31 20:11:57 +0000730 "ror{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000731 [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
732
733// Double shift instructions (generalizations of rotate)
734let isTwoAddress = 1 in {
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000735let Uses = [CL] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000736def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000737 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
738 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000739def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000740 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
741 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>, TB;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000742}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000743
744let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
745def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000746 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000747 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
748 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
749 (i8 imm:$src3)))]>,
750 TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000751def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000752 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000753 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
754 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
755 (i8 imm:$src3)))]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000756 TB;
757} // isCommutable
758} // isTwoAddress
759
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000760let Uses = [CL] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000761def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000762 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
763 [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
764 addr:$dst)]>, TB;
Evan Chengb783fa32007-07-19 01:14:50 +0000765def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000766 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
767 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
768 addr:$dst)]>, TB;
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000769}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000770def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000771 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000772 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
773 [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
774 (i8 imm:$src3)), addr:$dst)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000775 TB;
776def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000777 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
Dan Gohman4d9fc4a2007-09-14 23:17:45 +0000778 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
779 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
780 (i8 imm:$src3)), addr:$dst)]>,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000781 TB;
Evan Cheng55687072007-09-14 21:48:26 +0000782} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000783
784//===----------------------------------------------------------------------===//
785// Logical Instructions...
786//
787
Evan Cheng5b51c242009-01-21 19:45:31 +0000788let isTwoAddress = 1 , AddedComplexity = 15 in
Dan Gohman91888f02007-07-31 20:11:57 +0000789def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000790 [(set GR64:$dst, (not GR64:$src))]>;
Dan Gohman91888f02007-07-31 20:11:57 +0000791def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000792 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
793
Evan Cheng55687072007-09-14 21:48:26 +0000794let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000795let isTwoAddress = 1 in {
796let isCommutable = 1 in
797def AND64rr : RI<0x21, MRMDestReg,
Evan Chengb783fa32007-07-19 01:14:50 +0000798 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000799 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000800 [(set GR64:$dst, (and GR64:$src1, GR64:$src2)),
801 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000802def AND64rm : RI<0x23, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000803 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000804 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000805 [(set GR64:$dst, (and GR64:$src1, (load addr:$src2))),
806 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000807def AND64ri8 : RIi8<0x83, MRM4r,
Evan Chengb783fa32007-07-19 01:14:50 +0000808 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000809 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000810 [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2)),
811 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000812def AND64ri32 : RIi32<0x81, MRM4r,
813 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
814 "and{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000815 [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2)),
816 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000817} // isTwoAddress
818
819def AND64mr : RI<0x21, MRMDestMem,
Evan Chengb783fa32007-07-19 01:14:50 +0000820 (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000821 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000822 [(store (and (load addr:$dst), GR64:$src), addr:$dst),
823 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000824def AND64mi8 : RIi8<0x83, MRM4m,
Evan Chengb783fa32007-07-19 01:14:50 +0000825 (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000826 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000827 [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst),
828 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000829def AND64mi32 : RIi32<0x81, MRM4m,
830 (outs), (ins i64mem:$dst, i64i32imm:$src),
831 "and{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000832 [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
833 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000834
835let isTwoAddress = 1 in {
836let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000837def OR64rr : RI<0x09, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000838 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000839 [(set GR64:$dst, (or GR64:$src1, GR64:$src2)),
840 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000841def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000842 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000843 [(set GR64:$dst, (or GR64:$src1, (load addr:$src2))),
844 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000845def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000846 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000847 [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
848 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000849def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
850 "or{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000851 [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
852 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000853} // isTwoAddress
854
Evan Chengb783fa32007-07-19 01:14:50 +0000855def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000856 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000857 [(store (or (load addr:$dst), GR64:$src), addr:$dst),
858 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000859def OR64mi8 : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000860 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000861 [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst),
862 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000863def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src),
864 "or{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000865 [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
866 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000867
868let isTwoAddress = 1 in {
Evan Cheng0685efa2008-08-30 08:54:22 +0000869let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000870def XOR64rr : RI<0x31, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000871 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000872 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2)),
873 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000874def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000875 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000876 [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2))),
877 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000878def XOR64ri8 : RIi8<0x83, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
879 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000880 [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2)),
881 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000882def XOR64ri32 : RIi32<0x81, MRM6r,
Evan Chengb783fa32007-07-19 01:14:50 +0000883 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000884 "xor{q}\t{$src2, $dst|$dst, $src2}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000885 [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2)),
886 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000887} // isTwoAddress
888
Evan Chengb783fa32007-07-19 01:14:50 +0000889def XOR64mr : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000890 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000891 [(store (xor (load addr:$dst), GR64:$src), addr:$dst),
892 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000893def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
Dan Gohman91888f02007-07-31 20:11:57 +0000894 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000895 [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst),
896 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000897def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
898 "xor{q}\t{$src, $dst|$dst, $src}",
Dan Gohman7b93f1c2009-03-03 19:53:46 +0000899 [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
900 (implicit EFLAGS)]>;
Evan Cheng55687072007-09-14 21:48:26 +0000901} // Defs = [EFLAGS]
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000902
903//===----------------------------------------------------------------------===//
904// Comparison Instructions...
905//
906
907// Integer comparison
Evan Cheng55687072007-09-14 21:48:26 +0000908let Defs = [EFLAGS] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000909let isCommutable = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +0000910def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000911 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000912 [(X86cmp (and GR64:$src1, GR64:$src2), 0),
913 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000914def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000915 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000916 [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0),
917 (implicit EFLAGS)]>;
918def TEST64ri32 : RIi32<0xF7, MRM0r, (outs),
919 (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000920 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000921 [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0),
922 (implicit EFLAGS)]>;
923def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
924 (ins i64mem:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000925 "test{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000926 [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0),
927 (implicit EFLAGS)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000928
Evan Chengb783fa32007-07-19 01:14:50 +0000929def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000930 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000931 [(X86cmp GR64:$src1, GR64:$src2),
932 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000933def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000934 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000935 [(X86cmp (loadi64 addr:$src1), GR64:$src2),
936 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000937def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000938 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000939 [(X86cmp GR64:$src1, (loadi64 addr:$src2)),
940 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000941def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
942 "cmp{q}\t{$src2, $src1|$src1, $src2}",
943 [(X86cmp GR64:$src1, i64immSExt8:$src2),
944 (implicit EFLAGS)]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000945def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000946 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000947 [(X86cmp GR64:$src1, i64immSExt32:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000948 (implicit EFLAGS)]>;
Evan Cheng621216e2007-09-29 00:00:36 +0000949def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000950 "cmp{q}\t{$src2, $src1|$src1, $src2}",
Evan Cheng621216e2007-09-29 00:00:36 +0000951 [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +0000952 (implicit EFLAGS)]>;
Dan Gohmand16fdc02008-12-19 18:25:21 +0000953def CMP64mi32 : RIi32<0x81, MRM7m, (outs),
954 (ins i64mem:$src1, i64i32imm:$src2),
955 "cmp{q}\t{$src2, $src1|$src1, $src2}",
956 [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2),
957 (implicit EFLAGS)]>;
Evan Cheng950aac02007-09-25 01:57:46 +0000958} // Defs = [EFLAGS]
959
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000960// Bit tests.
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000961// TODO: BTC, BTR, and BTS
962let Defs = [EFLAGS] in {
Chris Lattner5a95cde2008-12-25 01:32:49 +0000963def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000964 "bt{q}\t{$src2, $src1|$src1, $src2}",
965 [(X86bt GR64:$src1, GR64:$src2),
Chris Lattner5a95cde2008-12-25 01:32:49 +0000966 (implicit EFLAGS)]>, TB;
Dan Gohman85a228c2009-01-13 23:23:30 +0000967
968// Unlike with the register+register form, the memory+register form of the
969// bt instruction does not ignore the high bits of the index. From ISel's
970// perspective, this is pretty bizarre. Disable these instructions for now.
971//def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
972// "bt{q}\t{$src2, $src1|$src1, $src2}",
973// [(X86bt (loadi64 addr:$src1), GR64:$src2),
974// (implicit EFLAGS)]>, TB;
Dan Gohman46fb1cf2009-01-13 20:33:23 +0000975
976def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
977 "bt{q}\t{$src2, $src1|$src1, $src2}",
978 [(X86bt GR64:$src1, i64immSExt8:$src2),
979 (implicit EFLAGS)]>, TB;
980// Note that these instructions don't need FastBTMem because that
981// only applies when the other operand is in a register. When it's
982// an immediate, bt is still fast.
983def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
984 "bt{q}\t{$src2, $src1|$src1, $src2}",
985 [(X86bt (loadi64 addr:$src1), i64immSExt8:$src2),
986 (implicit EFLAGS)]>, TB;
Dan Gohman7fe9b7f2008-12-23 22:45:23 +0000987} // Defs = [EFLAGS]
988
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000989// Conditional moves
Evan Cheng950aac02007-09-25 01:57:46 +0000990let Uses = [EFLAGS], isTwoAddress = 1 in {
Evan Cheng926658c2007-10-05 23:13:21 +0000991let isCommutable = 1 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000992def CMOVB64rr : RI<0x42, MRMSrcReg, // if <u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +0000993 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000994 "cmovb\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000995 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +0000996 X86_COND_B, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000997def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +0000998 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +0000999 "cmovae\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001000 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001001 X86_COND_AE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001002def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001003 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001004 "cmove\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001005 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001006 X86_COND_E, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001007def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001008 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001009 "cmovne\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001010 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001011 X86_COND_NE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001012def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64
Evan Chengb783fa32007-07-19 01:14:50 +00001013 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001014 "cmovbe\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001015 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
Evan Cheng621216e2007-09-29 00:00:36 +00001016 X86_COND_BE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001017def CMOVA64rr : RI<0x47, 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 "cmova\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_A, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001022def CMOVL64rr : RI<0x4C, MRMSrcReg, // if <s, 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 "cmovl\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_L, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001027def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, 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 "cmovge\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_GE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001032def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, 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 "cmovle\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_LE, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001037def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, 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 "cmovg\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_G, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001042def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, 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 "cmovs\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_S, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001047def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, 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 "cmovns\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_NS, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001052def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, 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 "cmovp\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_P, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001057def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, 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 "cmovnp\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_NP, EFLAGS))]>, TB;
Dan Gohman12fd4d72009-01-07 00:35:10 +00001062def CMOVO64rr : RI<0x40, MRMSrcReg, // if overflow, GR64 = GR64
1063 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1064 "cmovo\t{$src2, $dst|$dst, $src2}",
1065 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1066 X86_COND_O, EFLAGS))]>, TB;
1067def CMOVNO64rr : RI<0x41, MRMSrcReg, // if !overflow, GR64 = GR64
1068 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1069 "cmovno\t{$src2, $dst|$dst, $src2}",
1070 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1071 X86_COND_NO, EFLAGS))]>, TB;
Evan Cheng926658c2007-10-05 23:13:21 +00001072} // isCommutable = 1
1073
1074def CMOVB64rm : RI<0x42, MRMSrcMem, // if <u, GR64 = [mem64]
1075 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1076 "cmovb\t{$src2, $dst|$dst, $src2}",
1077 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1078 X86_COND_B, EFLAGS))]>, TB;
1079def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64]
1080 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1081 "cmovae\t{$src2, $dst|$dst, $src2}",
1082 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1083 X86_COND_AE, EFLAGS))]>, TB;
1084def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64]
1085 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1086 "cmove\t{$src2, $dst|$dst, $src2}",
1087 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1088 X86_COND_E, EFLAGS))]>, TB;
1089def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64]
1090 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1091 "cmovne\t{$src2, $dst|$dst, $src2}",
1092 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1093 X86_COND_NE, EFLAGS))]>, TB;
1094def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64]
1095 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1096 "cmovbe\t{$src2, $dst|$dst, $src2}",
1097 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1098 X86_COND_BE, EFLAGS))]>, TB;
1099def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64]
1100 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1101 "cmova\t{$src2, $dst|$dst, $src2}",
1102 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1103 X86_COND_A, EFLAGS))]>, TB;
1104def CMOVL64rm : RI<0x4C, MRMSrcMem, // if <s, GR64 = [mem64]
1105 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1106 "cmovl\t{$src2, $dst|$dst, $src2}",
1107 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1108 X86_COND_L, EFLAGS))]>, TB;
1109def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64]
1110 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1111 "cmovge\t{$src2, $dst|$dst, $src2}",
1112 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1113 X86_COND_GE, EFLAGS))]>, TB;
1114def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64]
1115 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1116 "cmovle\t{$src2, $dst|$dst, $src2}",
1117 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1118 X86_COND_LE, EFLAGS))]>, TB;
1119def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64]
1120 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1121 "cmovg\t{$src2, $dst|$dst, $src2}",
1122 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1123 X86_COND_G, EFLAGS))]>, TB;
1124def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64]
1125 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1126 "cmovs\t{$src2, $dst|$dst, $src2}",
1127 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1128 X86_COND_S, EFLAGS))]>, TB;
1129def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64]
1130 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1131 "cmovns\t{$src2, $dst|$dst, $src2}",
1132 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1133 X86_COND_NS, EFLAGS))]>, TB;
1134def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64]
1135 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1136 "cmovp\t{$src2, $dst|$dst, $src2}",
1137 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1138 X86_COND_P, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001139def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64]
Evan Chengb783fa32007-07-19 01:14:50 +00001140 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001141 "cmovnp\t{$src2, $dst|$dst, $src2}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001142 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
Evan Cheng950aac02007-09-25 01:57:46 +00001143 X86_COND_NP, EFLAGS))]>, TB;
Dan Gohman12fd4d72009-01-07 00:35:10 +00001144def CMOVO64rm : RI<0x40, MRMSrcMem, // if overflow, GR64 = [mem64]
1145 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1146 "cmovo\t{$src2, $dst|$dst, $src2}",
1147 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1148 X86_COND_O, EFLAGS))]>, TB;
1149def CMOVNO64rm : RI<0x41, MRMSrcMem, // if !overflow, GR64 = [mem64]
1150 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1151 "cmovno\t{$src2, $dst|$dst, $src2}",
1152 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1153 X86_COND_NO, EFLAGS))]>, TB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001154} // isTwoAddress
1155
1156//===----------------------------------------------------------------------===//
1157// Conversion Instructions...
1158//
1159
1160// f64 -> signed i64
Evan Chengb783fa32007-07-19 01:14:50 +00001161def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001162 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001163 [(set GR64:$dst,
1164 (int_x86_sse2_cvtsd2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001165def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001166 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001167 [(set GR64:$dst, (int_x86_sse2_cvtsd2si64
1168 (load addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001169def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001170 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001171 [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001172def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001173 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001174 [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001175def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001176 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001177 [(set GR64:$dst,
1178 (int_x86_sse2_cvttsd2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001179def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001180 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001181 [(set GR64:$dst,
1182 (int_x86_sse2_cvttsd2si64
1183 (load addr:$src)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001184
1185// Signed i64 -> f64
Evan Chengb783fa32007-07-19 01:14:50 +00001186def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001187 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001188 [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001189def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001190 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001191 [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng1d5832e2008-01-11 07:37:44 +00001192
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001193let isTwoAddress = 1 in {
1194def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
Evan Chengb783fa32007-07-19 01:14:50 +00001195 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001196 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6227d462007-07-23 03:07:27 +00001197 [(set VR128:$dst,
1198 (int_x86_sse2_cvtsi642sd VR128:$src1,
1199 GR64:$src2))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001200def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
Evan Chengb783fa32007-07-19 01:14:50 +00001201 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
Dan Gohman91888f02007-07-31 20:11:57 +00001202 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
Bill Wendling6227d462007-07-23 03:07:27 +00001203 [(set VR128:$dst,
1204 (int_x86_sse2_cvtsi642sd VR128:$src1,
1205 (loadi64 addr:$src2)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001206} // isTwoAddress
1207
1208// Signed i64 -> f32
Evan Chengb783fa32007-07-19 01:14:50 +00001209def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001210 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001211 [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001212def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001213 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001214 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
Evan Cheng1d5832e2008-01-11 07:37:44 +00001215
1216let isTwoAddress = 1 in {
1217 def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg,
1218 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1219 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1220 [(set VR128:$dst,
1221 (int_x86_sse_cvtsi642ss VR128:$src1,
1222 GR64:$src2))]>;
1223 def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem,
1224 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1225 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1226 [(set VR128:$dst,
1227 (int_x86_sse_cvtsi642ss VR128:$src1,
1228 (loadi64 addr:$src2)))]>;
1229}
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001230
1231// f32 -> signed i64
Evan Chengb783fa32007-07-19 01:14:50 +00001232def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001233 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001234 [(set GR64:$dst,
1235 (int_x86_sse_cvtss2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001236def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001237 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001238 [(set GR64:$dst, (int_x86_sse_cvtss2si64
1239 (load addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001240def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001241 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001242 [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001243def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001244 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001245 [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001246def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001247 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001248 [(set GR64:$dst,
1249 (int_x86_sse_cvttss2si64 VR128:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001250def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001251 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
Bill Wendling6227d462007-07-23 03:07:27 +00001252 [(set GR64:$dst,
1253 (int_x86_sse_cvttss2si64 (load addr:$src)))]>;
1254
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001255//===----------------------------------------------------------------------===//
1256// Alias Instructions
1257//===----------------------------------------------------------------------===//
1258
Dan Gohman027cd112007-09-17 14:55:08 +00001259// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
1260// equivalent due to implicit zero-extending, and it sometimes has a smaller
1261// encoding.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001262// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
1263// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
1264// when we have a better way to specify isel priority.
Bill Wendling12e97212008-05-30 06:47:04 +00001265let Defs = [EFLAGS], AddedComplexity = 1,
1266 isReMaterializable = 1, isAsCheapAsAMove = 1 in
Dan Gohman9203ab42008-07-30 18:09:17 +00001267def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins),
1268 "xor{l}\t${dst:subreg32}, ${dst:subreg32}",
1269 [(set GR64:$dst, 0)]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001270
1271// Materialize i64 constant where top 32-bits are zero.
Evan Chengbd0ca9c2009-02-05 08:42:55 +00001272let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Evan Chengb783fa32007-07-19 01:14:50 +00001273def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001274 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001275 [(set GR64:$dst, i64immZExt32:$src)]>;
1276
Anton Korobeynikov4fbf00b2008-05-04 21:36:32 +00001277//===----------------------------------------------------------------------===//
1278// Thread Local Storage Instructions
1279//===----------------------------------------------------------------------===//
1280
1281def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
Anton Korobeynikov5577e2e2008-05-05 17:08:59 +00001282 ".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
Anton Korobeynikov4fbf00b2008-05-04 21:36:32 +00001283 [(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001284
sampo9cc09a32009-01-26 01:24:32 +00001285let AddedComplexity = 5 in
1286def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1287 "movq\t%gs:$src, $dst",
1288 [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
1289
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001290//===----------------------------------------------------------------------===//
1291// Atomic Instructions
1292//===----------------------------------------------------------------------===//
1293
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001294let Defs = [RAX, EFLAGS], Uses = [RAX] in {
Evan Chengd49dbb82008-04-18 20:55:36 +00001295def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
Bill Wendling6f189e22008-08-19 23:09:18 +00001296 "lock\n\tcmpxchgq\t$swap,$ptr",
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001297 [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
1298}
1299
Dan Gohmana41a1c092008-08-06 15:52:50 +00001300let Constraints = "$val = $dst" in {
1301let Defs = [EFLAGS] in
Evan Chengd49dbb82008-04-18 20:55:36 +00001302def LXADD64 : RI<0xC1, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Bill Wendling6f189e22008-08-19 23:09:18 +00001303 "lock\n\txadd\t$val, $ptr",
Mon P Wang6bde9ec2008-06-25 08:15:39 +00001304 [(set GR64:$dst, (atomic_load_add_64 addr:$ptr, GR64:$val))]>,
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001305 TB, LOCK;
Evan Chenga1e80602008-04-19 02:05:42 +00001306def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
Bill Wendling6f189e22008-08-19 23:09:18 +00001307 "xchg\t$val, $ptr",
Evan Chenga1e80602008-04-19 02:05:42 +00001308 [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001309}
1310
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001311// Atomic exchange, and, or, xor
1312let Constraints = "$val = $dst", Defs = [EFLAGS],
1313 usesCustomDAGSchedInserter = 1 in {
1314def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001315 "#ATOMAND64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001316 [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001317def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001318 "#ATOMOR64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001319 [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001320def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001321 "#ATOMXOR64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001322 [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001323def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001324 "#ATOMNAND64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001325 [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001326def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001327 "#ATOMMIN64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001328 [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001329def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001330 "#ATOMMAX64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001331 [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001332def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001333 "#ATOMUMIN64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001334 [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001335def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
Nick Lewyckybfb9fd22008-12-07 03:49:52 +00001336 "#ATOMUMAX64 PSEUDO!",
Dale Johannesenbc187662008-08-28 02:44:49 +00001337 [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>;
Dale Johannesen6b60eca2008-08-20 00:48:50 +00001338}
Andrew Lenharthbd7d3262008-03-04 21:13:33 +00001339
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001340//===----------------------------------------------------------------------===//
1341// Non-Instruction Patterns
1342//===----------------------------------------------------------------------===//
1343
Bill Wendlingfef06052008-09-16 21:48:12 +00001344// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001345def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1346 (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
1347def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1348 (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
1349def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1350 (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
1351def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1352 (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
1353
1354def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1355 (MOV64mi32 addr:$dst, tconstpool:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001356 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001357def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1358 (MOV64mi32 addr:$dst, tjumptable:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001359 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001360def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1361 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001362 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001363def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1364 (MOV64mi32 addr:$dst, texternalsym:$src)>,
Evan Cheng3b5a1272008-02-07 08:53:49 +00001365 Requires<[SmallCode, IsStatic]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001366
1367// Calls
1368// Direct PC relative function call for small code model. 32-bit displacement
1369// sign extended to 64-bit.
1370def : Pat<(X86call (i64 tglobaladdr:$dst)),
1371 (CALL64pcrel32 tglobaladdr:$dst)>;
1372def : Pat<(X86call (i64 texternalsym:$dst)),
1373 (CALL64pcrel32 texternalsym:$dst)>;
1374
1375def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1376 (CALL64pcrel32 tglobaladdr:$dst)>;
1377def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1378 (CALL64pcrel32 texternalsym:$dst)>;
1379
1380def : Pat<(X86tailcall GR64:$dst),
1381 (CALL64r GR64:$dst)>;
1382
Arnold Schwaighofere2d6bbb2007-10-11 19:40:01 +00001383
1384// tailcall stuff
1385def : Pat<(X86tailcall GR32:$dst),
1386 (TAILCALL)>;
1387def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1388 (TAILCALL)>;
1389def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1390 (TAILCALL)>;
1391
1392def : Pat<(X86tcret GR64:$dst, imm:$off),
1393 (TCRETURNri64 GR64:$dst, imm:$off)>;
1394
1395def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1396 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1397
1398def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1399 (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1400
Dan Gohmanec596042007-09-17 14:35:24 +00001401// Comparisons.
1402
1403// TEST R,R is smaller than CMP R,0
Evan Cheng621216e2007-09-29 00:00:36 +00001404def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)),
Dan Gohmanec596042007-09-17 14:35:24 +00001405 (TEST64rr GR64:$src1, GR64:$src1)>;
1406
Dan Gohman0a3c5222009-01-07 01:00:24 +00001407// Conditional moves with folded loads with operands swapped and conditions
1408// inverted.
1409def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
1410 (CMOVAE64rm GR64:$src2, addr:$src1)>;
1411def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
1412 (CMOVB64rm GR64:$src2, addr:$src1)>;
1413def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
1414 (CMOVNE64rm GR64:$src2, addr:$src1)>;
1415def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
1416 (CMOVE64rm GR64:$src2, addr:$src1)>;
1417def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
1418 (CMOVA64rm GR64:$src2, addr:$src1)>;
1419def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
1420 (CMOVBE64rm GR64:$src2, addr:$src1)>;
1421def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
1422 (CMOVGE64rm GR64:$src2, addr:$src1)>;
1423def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
1424 (CMOVL64rm GR64:$src2, addr:$src1)>;
1425def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
1426 (CMOVG64rm GR64:$src2, addr:$src1)>;
1427def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
1428 (CMOVLE64rm GR64:$src2, addr:$src1)>;
1429def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
1430 (CMOVNP64rm GR64:$src2, addr:$src1)>;
1431def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
1432 (CMOVP64rm GR64:$src2, addr:$src1)>;
1433def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
1434 (CMOVNS64rm GR64:$src2, addr:$src1)>;
1435def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
1436 (CMOVS64rm GR64:$src2, addr:$src1)>;
1437def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
1438 (CMOVNO64rm GR64:$src2, addr:$src1)>;
1439def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
1440 (CMOVO64rm GR64:$src2, addr:$src1)>;
Christopher Lambb371e032008-03-13 05:47:01 +00001441
1442// Zero-extension
Christopher Lamb76d72da2008-03-16 03:12:01 +00001443def : Pat<(i64 (zext GR32:$src)),
1444 (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
Christopher Lambb371e032008-03-13 05:47:01 +00001445
Duncan Sands082524c2008-01-23 20:39:46 +00001446// zextload bool -> zextload byte
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001447def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1448
1449// extload
Dan Gohmanab460da2008-08-27 17:33:15 +00001450// When extloading from 16-bit and smaller memory locations into 64-bit registers,
1451// use zero-extending loads so that the entire 64-bit register is defined, avoiding
1452// partial-register updates.
1453def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1454def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
1455def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1456// For other extloads, use subregs, since the high contents of the register are
1457// defined after an extload.
Dan Gohmandd612bb2008-08-20 21:27:32 +00001458def : Pat<(extloadi64i32 addr:$src),
1459 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
1460 x86_subreg_32bit)>;
1461def : Pat<(extloadi16i1 addr:$src),
1462 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1463 x86_subreg_8bit)>,
1464 Requires<[In64BitMode]>;
1465def : Pat<(extloadi16i8 addr:$src),
1466 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
1467 x86_subreg_8bit)>,
1468 Requires<[In64BitMode]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001469
Dan Gohmandd612bb2008-08-20 21:27:32 +00001470// anyext
1471def : Pat<(i64 (anyext GR8:$src)),
1472 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
1473def : Pat<(i64 (anyext GR16:$src)),
1474 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
Christopher Lamb76d72da2008-03-16 03:12:01 +00001475def : Pat<(i64 (anyext GR32:$src)),
1476 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
Dan Gohmandd612bb2008-08-20 21:27:32 +00001477def : Pat<(i16 (anyext GR8:$src)),
1478 (INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1479 Requires<[In64BitMode]>;
1480def : Pat<(i32 (anyext GR8:$src)),
1481 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1482 Requires<[In64BitMode]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001483
1484//===----------------------------------------------------------------------===//
1485// Some peepholes
1486//===----------------------------------------------------------------------===//
1487
Dan Gohman5a5e6e92008-10-17 01:33:43 +00001488// Odd encoding trick: -128 fits into an 8-bit immediate field while
1489// +128 doesn't, so in this special case use a sub instead of an add.
1490def : Pat<(add GR64:$src1, 128),
1491 (SUB64ri8 GR64:$src1, -128)>;
1492def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1493 (SUB64mi8 addr:$dst, -128)>;
1494
1495// The same trick applies for 32-bit immediate fields in 64-bit
1496// instructions.
1497def : Pat<(add GR64:$src1, 0x0000000080000000),
1498 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1499def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
1500 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1501
Dan Gohman47a419d2008-08-07 02:54:50 +00001502// r & (2^32-1) ==> movz
Dan Gohman5a5e6e92008-10-17 01:33:43 +00001503def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
Dan Gohman47a419d2008-08-07 02:54:50 +00001504 (MOVZX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>;
Dan Gohman9203ab42008-07-30 18:09:17 +00001505// r & (2^16-1) ==> movz
1506def : Pat<(and GR64:$src, 0xffff),
1507 (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
1508// r & (2^8-1) ==> movz
1509def : Pat<(and GR64:$src, 0xff),
1510 (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
Dan Gohman9203ab42008-07-30 18:09:17 +00001511// r & (2^8-1) ==> movz
1512def : Pat<(and GR32:$src1, 0xff),
1513 (MOVZX32rr8 (i8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit)))>,
1514 Requires<[In64BitMode]>;
1515// r & (2^8-1) ==> movz
1516def : Pat<(and GR16:$src1, 0xff),
1517 (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
1518 Requires<[In64BitMode]>;
Christopher Lambb371e032008-03-13 05:47:01 +00001519
Dan Gohmandd612bb2008-08-20 21:27:32 +00001520// sext_inreg patterns
1521def : Pat<(sext_inreg GR64:$src, i32),
1522 (MOVSX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>;
1523def : Pat<(sext_inreg GR64:$src, i16),
1524 (MOVSX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
1525def : Pat<(sext_inreg GR64:$src, i8),
1526 (MOVSX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
1527def : Pat<(sext_inreg GR32:$src, i8),
1528 (MOVSX32rr8 (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)))>,
1529 Requires<[In64BitMode]>;
1530def : Pat<(sext_inreg GR16:$src, i8),
1531 (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
1532 Requires<[In64BitMode]>;
1533
1534// trunc patterns
1535def : Pat<(i32 (trunc GR64:$src)),
1536 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
1537def : Pat<(i16 (trunc GR64:$src)),
1538 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
1539def : Pat<(i8 (trunc GR64:$src)),
1540 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
1541def : Pat<(i8 (trunc GR32:$src)),
1542 (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
1543 Requires<[In64BitMode]>;
1544def : Pat<(i8 (trunc GR16:$src)),
1545 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit))>,
1546 Requires<[In64BitMode]>;
1547
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001548// (shl x, 1) ==> (add x, x)
1549def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1550
Evan Cheng76a64c72008-08-30 02:03:58 +00001551// (shl x (and y, 63)) ==> (shl x, y)
1552def : Pat<(shl GR64:$src1, (and CL:$amt, 63)),
1553 (SHL64rCL GR64:$src1)>;
1554def : Pat<(store (shl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1555 (SHL64mCL addr:$dst)>;
1556
1557def : Pat<(srl GR64:$src1, (and CL:$amt, 63)),
1558 (SHR64rCL GR64:$src1)>;
1559def : Pat<(store (srl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1560 (SHR64mCL addr:$dst)>;
1561
1562def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
1563 (SAR64rCL GR64:$src1)>;
1564def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1565 (SAR64mCL addr:$dst)>;
1566
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001567// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
1568def : Pat<(or (srl GR64:$src1, CL:$amt),
1569 (shl GR64:$src2, (sub 64, CL:$amt))),
1570 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1571
1572def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
1573 (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1574 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1575
Dan Gohman921581d2008-10-17 01:23:35 +00001576def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))),
1577 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1578 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1579
1580def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1581 (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1582 addr:$dst),
1583 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1584
1585def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1586 (SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1587
1588def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
1589 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1590 (SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1591
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001592// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
1593def : Pat<(or (shl GR64:$src1, CL:$amt),
1594 (srl GR64:$src2, (sub 64, CL:$amt))),
1595 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1596
1597def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
1598 (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1599 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1600
Dan Gohman921581d2008-10-17 01:23:35 +00001601def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))),
1602 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1603 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1604
1605def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1606 (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1607 addr:$dst),
1608 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1609
1610def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1611 (SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1612
1613def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
1614 GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1615 (SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1616
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001617// X86 specific add which produces a flag.
1618def : Pat<(addc GR64:$src1, GR64:$src2),
1619 (ADD64rr GR64:$src1, GR64:$src2)>;
1620def : Pat<(addc GR64:$src1, (load addr:$src2)),
1621 (ADD64rm GR64:$src1, addr:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001622def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
1623 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohmand16fdc02008-12-19 18:25:21 +00001624def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
1625 (ADD64ri32 GR64:$src1, imm:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001626
1627def : Pat<(subc GR64:$src1, GR64:$src2),
1628 (SUB64rr GR64:$src1, GR64:$src2)>;
1629def : Pat<(subc GR64:$src1, (load addr:$src2)),
1630 (SUB64rm GR64:$src1, addr:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001631def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
1632 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohmand16fdc02008-12-19 18:25:21 +00001633def : Pat<(subc GR64:$src1, imm:$src2),
1634 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001635
Bill Wendlingf5399032008-12-12 21:15:41 +00001636//===----------------------------------------------------------------------===//
Dan Gohman99a12192009-03-04 19:44:21 +00001637// EFLAGS-defining Patterns
Bill Wendlingf5399032008-12-12 21:15:41 +00001638//===----------------------------------------------------------------------===//
1639
Dan Gohman99a12192009-03-04 19:44:21 +00001640// Register-Register Addition with EFLAGS result
1641def : Pat<(parallel (X86add_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001642 (implicit EFLAGS)),
1643 (ADD64rr GR64:$src1, GR64:$src2)>;
1644
Dan Gohman99a12192009-03-04 19:44:21 +00001645// Register-Integer Addition with EFLAGS result
1646def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001647 (implicit EFLAGS)),
1648 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001649def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001650 (implicit EFLAGS)),
1651 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001652
Dan Gohman99a12192009-03-04 19:44:21 +00001653// Register-Memory Addition with EFLAGS result
1654def : Pat<(parallel (X86add_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001655 (implicit EFLAGS)),
1656 (ADD64rm GR64:$src1, addr:$src2)>;
1657
Dan Gohman99a12192009-03-04 19:44:21 +00001658// Memory-Register Addition with EFLAGS result
1659def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001660 addr:$dst),
1661 (implicit EFLAGS)),
1662 (ADD64mr addr:$dst, GR64:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001663def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001664 addr:$dst),
1665 (implicit EFLAGS)),
1666 (ADD64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001667def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001668 addr:$dst),
1669 (implicit EFLAGS)),
1670 (ADD64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001671
Dan Gohman99a12192009-03-04 19:44:21 +00001672// Register-Register Subtraction with EFLAGS result
1673def : Pat<(parallel (X86sub_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001674 (implicit EFLAGS)),
1675 (SUB64rr GR64:$src1, GR64:$src2)>;
1676
Dan Gohman99a12192009-03-04 19:44:21 +00001677// Register-Memory Subtraction with EFLAGS result
1678def : Pat<(parallel (X86sub_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001679 (implicit EFLAGS)),
1680 (SUB64rm GR64:$src1, addr:$src2)>;
1681
Dan Gohman99a12192009-03-04 19:44:21 +00001682// Register-Integer Subtraction with EFLAGS result
1683def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001684 (implicit EFLAGS)),
1685 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001686def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001687 (implicit EFLAGS)),
1688 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001689
Dan Gohman99a12192009-03-04 19:44:21 +00001690// Memory-Register Subtraction with EFLAGS result
1691def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001692 addr:$dst),
1693 (implicit EFLAGS)),
1694 (SUB64mr addr:$dst, GR64:$src2)>;
1695
Dan Gohman99a12192009-03-04 19:44:21 +00001696// Memory-Integer Subtraction with EFLAGS result
1697def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001698 addr:$dst),
1699 (implicit EFLAGS)),
1700 (SUB64mi8 addr:$dst, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001701def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001702 addr:$dst),
1703 (implicit EFLAGS)),
1704 (SUB64mi32 addr:$dst, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001705
Dan Gohman99a12192009-03-04 19:44:21 +00001706// Register-Register Signed Integer Multiplication with EFLAGS result
1707def : Pat<(parallel (X86smul_flag GR64:$src1, GR64:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001708 (implicit EFLAGS)),
1709 (IMUL64rr GR64:$src1, GR64:$src2)>;
1710
Dan Gohman99a12192009-03-04 19:44:21 +00001711// Register-Memory Signed Integer Multiplication with EFLAGS result
1712def : Pat<(parallel (X86smul_flag GR64:$src1, (loadi64 addr:$src2)),
Bill Wendlingf5399032008-12-12 21:15:41 +00001713 (implicit EFLAGS)),
1714 (IMUL64rm GR64:$src1, addr:$src2)>;
1715
Dan Gohman99a12192009-03-04 19:44:21 +00001716// Register-Integer Signed Integer Multiplication with EFLAGS result
1717def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001718 (implicit EFLAGS)),
1719 (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001720def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001721 (implicit EFLAGS)),
1722 (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
Bill Wendlingf5399032008-12-12 21:15:41 +00001723
Dan Gohman99a12192009-03-04 19:44:21 +00001724// Memory-Integer Signed Integer Multiplication with EFLAGS result
1725def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt8:$src2),
Bill Wendlingf5399032008-12-12 21:15:41 +00001726 (implicit EFLAGS)),
1727 (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
Dan Gohman99a12192009-03-04 19:44:21 +00001728def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt32:$src2),
Dan Gohmand16fdc02008-12-19 18:25:21 +00001729 (implicit EFLAGS)),
1730 (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001731
Dan Gohman99a12192009-03-04 19:44:21 +00001732// INC and DEC with EFLAGS result. Note that these do not set CF.
Dan Gohmaneebcac72009-03-05 21:32:23 +00001733def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)),
1734 (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1735def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst),
1736 (implicit EFLAGS)),
1737 (INC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1738def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)),
1739 (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1740def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst),
1741 (implicit EFLAGS)),
1742 (DEC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1743
1744def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)),
1745 (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1746def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst),
1747 (implicit EFLAGS)),
1748 (INC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1749def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)),
1750 (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1751def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst),
1752 (implicit EFLAGS)),
1753 (DEC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1754
Dan Gohman99a12192009-03-04 19:44:21 +00001755def : Pat<(parallel (X86inc_flag GR64:$src), (implicit EFLAGS)),
1756 (INC64r GR64:$src)>;
1757def : Pat<(parallel (store (i64 (X86inc_flag (loadi64 addr:$dst))), addr:$dst),
1758 (implicit EFLAGS)),
1759 (INC64m addr:$dst)>;
1760def : Pat<(parallel (X86dec_flag GR64:$src), (implicit EFLAGS)),
1761 (DEC64r GR64:$src)>;
1762def : Pat<(parallel (store (i64 (X86dec_flag (loadi64 addr:$dst))), addr:$dst),
1763 (implicit EFLAGS)),
1764 (DEC64m addr:$dst)>;
1765
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001766//===----------------------------------------------------------------------===//
1767// X86-64 SSE Instructions
1768//===----------------------------------------------------------------------===//
1769
1770// Move instructions...
1771
Evan Chengb783fa32007-07-19 01:14:50 +00001772def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001773 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001774 [(set VR128:$dst,
1775 (v2i64 (scalar_to_vector GR64:$src)))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001776def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001777 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001778 [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
1779 (iPTR 0)))]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001780
Evan Chengb783fa32007-07-19 01:14:50 +00001781def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001782 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001783 [(set FR64:$dst, (bitconvert GR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001784def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
Evan Cheng69ca4da2008-08-25 04:11:42 +00001785 "movq\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001786 [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
1787
Evan Chengb783fa32007-07-19 01:14:50 +00001788def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
Dan Gohman91888f02007-07-31 20:11:57 +00001789 "mov{d|q}\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001790 [(set GR64:$dst, (bitconvert FR64:$src))]>;
Evan Chengb783fa32007-07-19 01:14:50 +00001791def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
Evan Cheng69ca4da2008-08-25 04:11:42 +00001792 "movq\t{$src, $dst|$dst, $src}",
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001793 [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
Nate Begemanb2975562008-02-03 07:18:54 +00001794
1795//===----------------------------------------------------------------------===//
1796// X86-64 SSE4.1 Instructions
1797//===----------------------------------------------------------------------===//
1798
Nate Begeman4294c1f2008-02-12 22:51:28 +00001799/// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
1800multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
Nate Begeman0050ab52008-10-29 23:07:17 +00001801 def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001802 (ins VR128:$src1, i32i8imm:$src2),
1803 !strconcat(OpcodeStr,
1804 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1805 [(set GR64:$dst,
1806 (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
Evan Cheng78d00612008-03-14 07:39:27 +00001807 def mr : SS4AIi8<opc, MRMDestMem, (outs),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001808 (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
1809 !strconcat(OpcodeStr,
1810 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1811 [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
1812 addr:$dst)]>, OpSize, REX_W;
1813}
1814
1815defm PEXTRQ : SS41I_extract64<0x16, "pextrq">;
1816
1817let isTwoAddress = 1 in {
1818 multiclass SS41I_insert64<bits<8> opc, string OpcodeStr> {
Evan Cheng78d00612008-03-14 07:39:27 +00001819 def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001820 (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
1821 !strconcat(OpcodeStr,
1822 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1823 [(set VR128:$dst,
1824 (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
1825 OpSize, REX_W;
Evan Cheng78d00612008-03-14 07:39:27 +00001826 def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
Nate Begeman4294c1f2008-02-12 22:51:28 +00001827 (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
1828 !strconcat(OpcodeStr,
1829 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1830 [(set VR128:$dst,
1831 (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
1832 imm:$src3)))]>, OpSize, REX_W;
1833 }
1834}
1835
1836defm PINSRQ : SS41I_insert64<0x22, "pinsrq">;