1 //===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the integer arithmetic instructions in the X86
13 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // LEA - Load Effective Address
17 let SchedRW = [WriteLEA] in {
18 let hasSideEffects = 0 in
19 def LEA16r : I<0x8D, MRMSrcMem,
20 (outs GR16:$dst), (ins anymem:$src),
21 "lea{w}\t{$src|$dst}, {$dst|$src}", [], IIC_LEA_16>, OpSize16;
22 let isReMaterializable = 1 in
23 def LEA32r : I<0x8D, MRMSrcMem,
24 (outs GR32:$dst), (ins anymem:$src),
25 "lea{l}\t{$src|$dst}, {$dst|$src}",
26 [(set GR32:$dst, lea32addr:$src)], IIC_LEA>,
27 OpSize32, Requires<[Not64BitMode]>;
29 def LEA64_32r : I<0x8D, MRMSrcMem,
30 (outs GR32:$dst), (ins lea64_32mem:$src),
31 "lea{l}\t{$src|$dst}, {$dst|$src}",
32 [(set GR32:$dst, lea64_32addr:$src)], IIC_LEA>,
33 OpSize32, Requires<[In64BitMode]>;
35 let isReMaterializable = 1 in
36 def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
37 "lea{q}\t{$src|$dst}, {$dst|$src}",
38 [(set GR64:$dst, lea64addr:$src)], IIC_LEA>;
41 //===----------------------------------------------------------------------===//
42 // Fixed-Register Multiplication and Division Instructions.
45 // SchedModel info for instruction that loads one value and gets the second
46 // (and possibly third) value from a register.
47 // This is used for instructions that put the memory operands before other
49 class SchedLoadReg<SchedWrite SW> : Sched<[SW,
51 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
52 // Register reads (implicit or explicit).
53 ReadAfterLd, ReadAfterLd]>;
55 // Extra precision multiplication
57 // AL is really implied by AX, but the registers in Defs must match the
58 // SDNode results (i8, i32).
60 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
61 def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
62 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
63 // This probably ought to be moved to a def : Pat<> if the
64 // syntax can be accepted.
65 [(set AL, (mul AL, GR8:$src)),
66 (implicit EFLAGS)], IIC_MUL8>, Sched<[WriteIMul]>;
68 let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
69 def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src),
71 [], IIC_MUL16_REG>, OpSize16, Sched<[WriteIMul]>;
73 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
74 def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src),
76 [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/],
77 IIC_MUL32_REG>, OpSize32, Sched<[WriteIMul]>;
79 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
80 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
82 [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/],
83 IIC_MUL64>, Sched<[WriteIMul]>;
85 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
86 def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
88 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
89 // This probably ought to be moved to a def : Pat<> if the
90 // syntax can be accepted.
91 [(set AL, (mul AL, (loadi8 addr:$src))),
92 (implicit EFLAGS)], IIC_MUL8>, SchedLoadReg<WriteIMulLd>;
94 let mayLoad = 1, hasSideEffects = 0 in {
95 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
96 def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
98 [], IIC_MUL16_MEM>, OpSize16, SchedLoadReg<WriteIMulLd>;
99 // EAX,EDX = EAX*[mem32]
100 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
101 def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
103 [], IIC_MUL32_MEM>, OpSize32, SchedLoadReg<WriteIMulLd>;
104 // RAX,RDX = RAX*[mem64]
105 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
106 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
107 "mul{q}\t$src", [], IIC_MUL64>, SchedLoadReg<WriteIMulLd>,
108 Requires<[In64BitMode]>;
111 let hasSideEffects = 0 in {
113 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
114 def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", [],
115 IIC_IMUL8>, Sched<[WriteIMul]>;
117 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
118 def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", [],
119 IIC_IMUL16_RR>, OpSize16, Sched<[WriteIMul]>;
120 // EAX,EDX = EAX*GR32
121 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
122 def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", [],
123 IIC_IMUL32_RR>, OpSize32, Sched<[WriteIMul]>;
124 // RAX,RDX = RAX*GR64
125 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
126 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
127 IIC_IMUL64_RR>, Sched<[WriteIMul]>;
131 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
132 def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
133 "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
134 // AX,DX = AX*[mem16]
135 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
136 def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
137 "imul{w}\t$src", [], IIC_IMUL16_MEM>, OpSize16,
138 SchedLoadReg<WriteIMulLd>;
139 // EAX,EDX = EAX*[mem32]
140 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
141 def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
142 "imul{l}\t$src", [], IIC_IMUL32_MEM>, OpSize32,
143 SchedLoadReg<WriteIMulLd>;
144 // RAX,RDX = RAX*[mem64]
145 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
146 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
147 "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>,
148 Requires<[In64BitMode]>;
153 let Defs = [EFLAGS] in {
154 let Constraints = "$src1 = $dst" in {
156 let isCommutable = 1, SchedRW = [WriteIMul] in {
157 // X = IMUL Y, Z --> X = IMUL Z, Y
158 // Register-Register Signed Integer Multiply
159 def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
160 "imul{w}\t{$src2, $dst|$dst, $src2}",
161 [(set GR16:$dst, EFLAGS,
162 (X86smul_flag GR16:$src1, GR16:$src2))], IIC_IMUL16_RR>,
164 def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
165 "imul{l}\t{$src2, $dst|$dst, $src2}",
166 [(set GR32:$dst, EFLAGS,
167 (X86smul_flag GR32:$src1, GR32:$src2))], IIC_IMUL32_RR>,
169 def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
170 (ins GR64:$src1, GR64:$src2),
171 "imul{q}\t{$src2, $dst|$dst, $src2}",
172 [(set GR64:$dst, EFLAGS,
173 (X86smul_flag GR64:$src1, GR64:$src2))], IIC_IMUL64_RR>,
175 } // isCommutable, SchedRW
177 // Register-Memory Signed Integer Multiply
178 let SchedRW = [WriteIMulLd, ReadAfterLd] in {
179 def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
180 (ins GR16:$src1, i16mem:$src2),
181 "imul{w}\t{$src2, $dst|$dst, $src2}",
182 [(set GR16:$dst, EFLAGS,
183 (X86smul_flag GR16:$src1, (load addr:$src2)))],
186 def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
187 (ins GR32:$src1, i32mem:$src2),
188 "imul{l}\t{$src2, $dst|$dst, $src2}",
189 [(set GR32:$dst, EFLAGS,
190 (X86smul_flag GR32:$src1, (load addr:$src2)))],
193 def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
194 (ins GR64:$src1, i64mem:$src2),
195 "imul{q}\t{$src2, $dst|$dst, $src2}",
196 [(set GR64:$dst, EFLAGS,
197 (X86smul_flag GR64:$src1, (load addr:$src2)))],
201 } // Constraints = "$src1 = $dst"
205 // Surprisingly enough, these are not two address instructions!
206 let Defs = [EFLAGS] in {
207 let SchedRW = [WriteIMul] in {
208 // Register-Integer Signed Integer Multiply
209 def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16
210 (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
211 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
212 [(set GR16:$dst, EFLAGS,
213 (X86smul_flag GR16:$src1, imm:$src2))],
214 IIC_IMUL16_RRI>, OpSize16;
215 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // GR16 = GR16*I8
216 (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
217 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
218 [(set GR16:$dst, EFLAGS,
219 (X86smul_flag GR16:$src1, i16immSExt8:$src2))],
220 IIC_IMUL16_RRI>, OpSize16;
221 def IMUL32rri : Ii32<0x69, MRMSrcReg, // GR32 = GR32*I32
222 (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
223 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
224 [(set GR32:$dst, EFLAGS,
225 (X86smul_flag GR32:$src1, imm:$src2))],
226 IIC_IMUL32_RRI>, OpSize32;
227 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8
228 (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
229 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
230 [(set GR32:$dst, EFLAGS,
231 (X86smul_flag GR32:$src1, i32immSExt8:$src2))],
232 IIC_IMUL32_RRI>, OpSize32;
233 def IMUL64rri32 : RIi32S<0x69, MRMSrcReg, // GR64 = GR64*I32
234 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
235 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
236 [(set GR64:$dst, EFLAGS,
237 (X86smul_flag GR64:$src1, i64immSExt32:$src2))],
239 def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
240 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
241 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
242 [(set GR64:$dst, EFLAGS,
243 (X86smul_flag GR64:$src1, i64immSExt8:$src2))],
247 // Memory-Integer Signed Integer Multiply
248 let SchedRW = [WriteIMulLd] in {
249 def IMUL16rmi : Ii16<0x69, MRMSrcMem, // GR16 = [mem16]*I16
250 (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
251 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
252 [(set GR16:$dst, EFLAGS,
253 (X86smul_flag (load addr:$src1), imm:$src2))],
256 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // GR16 = [mem16]*I8
257 (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
258 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
259 [(set GR16:$dst, EFLAGS,
260 (X86smul_flag (load addr:$src1),
261 i16immSExt8:$src2))], IIC_IMUL16_RMI>,
263 def IMUL32rmi : Ii32<0x69, MRMSrcMem, // GR32 = [mem32]*I32
264 (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
265 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
266 [(set GR32:$dst, EFLAGS,
267 (X86smul_flag (load addr:$src1), imm:$src2))],
268 IIC_IMUL32_RMI>, OpSize32;
269 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8
270 (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
271 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
272 [(set GR32:$dst, EFLAGS,
273 (X86smul_flag (load addr:$src1),
274 i32immSExt8:$src2))],
275 IIC_IMUL32_RMI>, OpSize32;
276 def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem, // GR64 = [mem64]*I32
277 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
278 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
279 [(set GR64:$dst, EFLAGS,
280 (X86smul_flag (load addr:$src1),
281 i64immSExt32:$src2))],
283 def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
284 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
285 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
286 [(set GR64:$dst, EFLAGS,
287 (X86smul_flag (load addr:$src1),
288 i64immSExt8:$src2))],
296 // unsigned division/remainder
297 let hasSideEffects = 1 in { // so that we don't speculatively execute
298 let SchedRW = [WriteIDiv] in {
299 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
300 def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
301 "div{b}\t$src", [], IIC_DIV8_REG>;
302 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
303 def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
304 "div{w}\t$src", [], IIC_DIV16>, OpSize16;
305 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
306 def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
307 "div{l}\t$src", [], IIC_DIV32>, OpSize32;
308 // RDX:RAX/r64 = RAX,RDX
309 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
310 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
311 "div{q}\t$src", [], IIC_DIV64>;
315 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
316 def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
317 "div{b}\t$src", [], IIC_DIV8_MEM>,
318 SchedLoadReg<WriteIDivLd>;
319 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
320 def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
321 "div{w}\t$src", [], IIC_DIV16>, OpSize16,
322 SchedLoadReg<WriteIDivLd>;
323 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
324 def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
325 "div{l}\t$src", [], IIC_DIV32>,
326 SchedLoadReg<WriteIDivLd>, OpSize32;
327 // RDX:RAX/[mem64] = RAX,RDX
328 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
329 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
330 "div{q}\t$src", [], IIC_DIV64>,
331 SchedLoadReg<WriteIDivLd>, Requires<[In64BitMode]>;
334 // Signed division/remainder.
335 let SchedRW = [WriteIDiv] in {
336 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
337 def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
338 "idiv{b}\t$src", [], IIC_IDIV8>;
339 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
340 def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
341 "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16;
342 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
343 def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
344 "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32;
345 // RDX:RAX/r64 = RAX,RDX
346 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
347 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
348 "idiv{q}\t$src", [], IIC_IDIV64>;
352 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
353 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
354 "idiv{b}\t$src", [], IIC_IDIV8>,
355 SchedLoadReg<WriteIDivLd>;
356 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
357 def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
358 "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16,
359 SchedLoadReg<WriteIDivLd>;
360 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
361 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
362 "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32,
363 SchedLoadReg<WriteIDivLd>;
364 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
365 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
366 "idiv{q}\t$src", [], IIC_IDIV64>,
367 SchedLoadReg<WriteIDivLd>, Requires<[In64BitMode]>;
369 } // hasSideEffects = 0
371 //===----------------------------------------------------------------------===//
372 // Two address Instructions.
375 // unary instructions
376 let CodeSize = 2 in {
377 let Defs = [EFLAGS] in {
378 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
379 def NEG8r : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
381 [(set GR8:$dst, (ineg GR8:$src1)),
382 (implicit EFLAGS)], IIC_UNARY_REG>;
383 def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
385 [(set GR16:$dst, (ineg GR16:$src1)),
386 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize16;
387 def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
389 [(set GR32:$dst, (ineg GR32:$src1)),
390 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize32;
391 def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
392 [(set GR64:$dst, (ineg GR64:$src1)),
393 (implicit EFLAGS)], IIC_UNARY_REG>;
394 } // Constraints = "$src1 = $dst", SchedRW
396 // Read-modify-write negate.
397 let SchedRW = [WriteALULd, WriteRMW] in {
398 def NEG8m : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
400 [(store (ineg (loadi8 addr:$dst)), addr:$dst),
401 (implicit EFLAGS)], IIC_UNARY_MEM>;
402 def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
404 [(store (ineg (loadi16 addr:$dst)), addr:$dst),
405 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize16;
406 def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
408 [(store (ineg (loadi32 addr:$dst)), addr:$dst),
409 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize32;
410 def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
411 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
412 (implicit EFLAGS)], IIC_UNARY_MEM>,
413 Requires<[In64BitMode]>;
418 // Note: NOT does not set EFLAGS!
420 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
421 // Match xor -1 to not. Favors these over a move imm + xor to save code size.
422 let AddedComplexity = 15 in {
423 def NOT8r : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
425 [(set GR8:$dst, (not GR8:$src1))], IIC_UNARY_REG>;
426 def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
428 [(set GR16:$dst, (not GR16:$src1))], IIC_UNARY_REG>, OpSize16;
429 def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
431 [(set GR32:$dst, (not GR32:$src1))], IIC_UNARY_REG>, OpSize32;
432 def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
433 [(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
435 } // Constraints = "$src1 = $dst", SchedRW
437 let SchedRW = [WriteALULd, WriteRMW] in {
438 def NOT8m : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
440 [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
441 def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
443 [(store (not (loadi16 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
445 def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
447 [(store (not (loadi32 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
449 def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
450 [(store (not (loadi64 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
451 Requires<[In64BitMode]>;
455 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
456 let Defs = [EFLAGS] in {
457 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
459 def INC8r : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
461 [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))],
463 let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
464 def INC16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
466 [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))],
467 IIC_UNARY_REG>, OpSize16;
468 def INC32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
470 [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
471 IIC_UNARY_REG>, OpSize32;
472 def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
473 [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
475 } // isConvertibleToThreeAddress = 1, CodeSize = 2
477 // Short forms only valid in 32-bit mode. Selected during MCInst lowering.
478 let CodeSize = 1, hasSideEffects = 0 in {
479 def INC16r_alt : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
480 "inc{w}\t$dst", [], IIC_UNARY_REG>,
481 OpSize16, Requires<[Not64BitMode]>;
482 def INC32r_alt : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
483 "inc{l}\t$dst", [], IIC_UNARY_REG>,
484 OpSize32, Requires<[Not64BitMode]>;
485 } // CodeSize = 1, hasSideEffects = 0
486 } // Constraints = "$src1 = $dst", SchedRW
488 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
489 let Predicates = [UseIncDec] in {
490 def INC8m : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
491 [(store (add (loadi8 addr:$dst), 1), addr:$dst),
492 (implicit EFLAGS)], IIC_UNARY_MEM>;
493 def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
494 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
495 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize16;
496 def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
497 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
498 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize32;
500 let Predicates = [UseIncDec, In64BitMode] in {
501 def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
502 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
503 (implicit EFLAGS)], IIC_UNARY_MEM>;
505 } // CodeSize = 2, SchedRW
507 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
509 def DEC8r : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
511 [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
513 let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
514 def DEC16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
516 [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
517 IIC_UNARY_REG>, OpSize16;
518 def DEC32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
520 [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
521 IIC_UNARY_REG>, OpSize32;
522 def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
523 [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
525 } // isConvertibleToThreeAddress = 1, CodeSize = 2
527 // Short forms only valid in 32-bit mode. Selected during MCInst lowering.
528 let CodeSize = 1, hasSideEffects = 0 in {
529 def DEC16r_alt : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
530 "dec{w}\t$dst", [], IIC_UNARY_REG>,
531 OpSize16, Requires<[Not64BitMode]>;
532 def DEC32r_alt : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
533 "dec{l}\t$dst", [], IIC_UNARY_REG>,
534 OpSize32, Requires<[Not64BitMode]>;
535 } // CodeSize = 1, hasSideEffects = 0
536 } // Constraints = "$src1 = $dst", SchedRW
539 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
540 let Predicates = [UseIncDec] in {
541 def DEC8m : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
542 [(store (add (loadi8 addr:$dst), -1), addr:$dst),
543 (implicit EFLAGS)], IIC_UNARY_MEM>;
544 def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
545 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
546 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize16;
547 def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
548 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
549 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize32;
551 let Predicates = [UseIncDec, In64BitMode] in {
552 def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
553 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
554 (implicit EFLAGS)], IIC_UNARY_MEM>;
556 } // CodeSize = 2, SchedRW
559 /// X86TypeInfo - This is a bunch of information that describes relevant X86
560 /// information about value types. For example, it can tell you what the
561 /// register class and preferred load to use.
562 class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
563 PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
564 Operand immoperand, SDPatternOperator immoperator,
565 Operand imm8operand, SDPatternOperator imm8operator,
566 bit hasOddOpcode, OperandSize opSize,
567 bit hasREX_WPrefix> {
568 /// VT - This is the value type itself.
571 /// InstrSuffix - This is the suffix used on instructions with this type. For
572 /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
573 string InstrSuffix = instrsuffix;
575 /// RegClass - This is the register class associated with this type. For
576 /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
577 RegisterClass RegClass = regclass;
579 /// LoadNode - This is the load node associated with this type. For
580 /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
581 PatFrag LoadNode = loadnode;
583 /// MemOperand - This is the memory operand associated with this type. For
584 /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
585 X86MemOperand MemOperand = memoperand;
587 /// ImmEncoding - This is the encoding of an immediate of this type. For
588 /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32. Note that i64 -> Imm32
589 /// since the immediate fields of i64 instructions is a 32-bit sign extended
591 ImmType ImmEncoding = immkind;
593 /// ImmOperand - This is the operand kind of an immediate of this type. For
594 /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm. Note that i64 ->
595 /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
597 Operand ImmOperand = immoperand;
599 /// ImmOperator - This is the operator that should be used to match an
600 /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
601 SDPatternOperator ImmOperator = immoperator;
603 /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
604 /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm. This is
605 /// only used for instructions that have a sign-extended imm8 field form.
606 Operand Imm8Operand = imm8operand;
608 /// Imm8Operator - This is the operator that should be used to match an 8-bit
609 /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
610 SDPatternOperator Imm8Operator = imm8operator;
612 /// HasOddOpcode - This bit is true if the instruction should have an odd (as
613 /// opposed to even) opcode. Operations on i8 are usually even, operations on
614 /// other datatypes are odd.
615 bit HasOddOpcode = hasOddOpcode;
617 /// OpSize - Selects whether the instruction needs a 0x66 prefix based on
618 /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this
619 /// to Opsize16. i32 sets this to OpSize32.
620 OperandSize OpSize = opSize;
622 /// HasREX_WPrefix - This bit is set to true if the instruction should have
623 /// the 0x40 REX prefix. This is set for i64 types.
624 bit HasREX_WPrefix = hasREX_WPrefix;
627 def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
630 def Xi8 : X86TypeInfo<i8, "b", GR8, loadi8, i8mem,
631 Imm8, i8imm, imm8_su, i8imm, invalid_node,
633 def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
634 Imm16, i16imm, imm16_su, i16i8imm, i16immSExt8_su,
636 def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
637 Imm32, i32imm, imm32_su, i32i8imm, i32immSExt8_su,
639 def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
640 Imm32S, i64i32imm, i64immSExt32_su, i64i8imm, i64immSExt8_su,
643 /// ITy - This instruction base class takes the type info for the instruction.
645 /// 1. Concatenates together the instruction mnemonic with the appropriate
646 /// suffix letter, a tab, and the arguments.
647 /// 2. Infers whether the instruction should have a 0x66 prefix byte.
648 /// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
649 /// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
650 /// or 1 (for i16,i32,i64 operations).
651 class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
652 string mnemonic, string args, list<dag> pattern,
653 InstrItinClass itin = IIC_BIN_NONMEM>
654 : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
655 opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
657 !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
660 // Infer instruction prefixes from type info.
661 let OpSize = typeinfo.OpSize;
662 let hasREX_WPrefix = typeinfo.HasREX_WPrefix;
665 // BinOpRR - Instructions like "add reg, reg, reg".
666 class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
667 dag outlist, list<dag> pattern, InstrItinClass itin>
668 : ITy<opcode, MRMDestReg, typeinfo, outlist,
669 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
670 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
673 // BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
674 // just a EFLAGS as a result.
675 class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
676 SDPatternOperator opnode>
677 : BinOpRR<opcode, mnemonic, typeinfo, (outs),
679 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
682 // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
683 // both a regclass and EFLAGS as a result.
684 class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
686 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
687 [(set typeinfo.RegClass:$dst, EFLAGS,
688 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
691 // BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
692 // both a regclass and EFLAGS as a result, and has EFLAGS as input.
693 class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
695 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
696 [(set typeinfo.RegClass:$dst, EFLAGS,
697 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
698 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
700 // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
701 class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
702 InstrItinClass itin = IIC_BIN_NONMEM>
703 : ITy<opcode, MRMSrcReg, typeinfo,
704 (outs typeinfo.RegClass:$dst),
705 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
706 mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
708 // The disassembler should know about this, but not the asmparser.
709 let isCodeGenOnly = 1;
710 let ForceDisassemble = 1;
711 let hasSideEffects = 0;
714 // BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
715 class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
716 : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
718 // BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
719 class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
720 : ITy<opcode, MRMSrcReg, typeinfo, (outs),
721 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
722 mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
724 // The disassembler should know about this, but not the asmparser.
725 let isCodeGenOnly = 1;
726 let ForceDisassemble = 1;
727 let hasSideEffects = 0;
730 // BinOpRM - Instructions like "add reg, reg, [mem]".
731 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
732 dag outlist, list<dag> pattern,
733 InstrItinClass itin = IIC_BIN_MEM>
734 : ITy<opcode, MRMSrcMem, typeinfo, outlist,
735 (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
736 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
737 Sched<[WriteALULd, ReadAfterLd]>;
739 // BinOpRM_F - Instructions like "cmp reg, [mem]".
740 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
742 : BinOpRM<opcode, mnemonic, typeinfo, (outs),
744 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
746 // BinOpRM_RF - Instructions like "add reg, reg, [mem]".
747 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
749 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
750 [(set typeinfo.RegClass:$dst, EFLAGS,
751 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
753 // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
754 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
756 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
757 [(set typeinfo.RegClass:$dst, EFLAGS,
758 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
759 EFLAGS))], IIC_BIN_CARRY_MEM>;
761 // BinOpRI - Instructions like "add reg, reg, imm".
762 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
763 Format f, dag outlist, list<dag> pattern,
764 InstrItinClass itin = IIC_BIN_NONMEM>
765 : ITy<opcode, f, typeinfo, outlist,
766 (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
767 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
769 let ImmT = typeinfo.ImmEncoding;
772 // BinOpRI_F - Instructions like "cmp reg, imm".
773 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
774 SDPatternOperator opnode, Format f>
775 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
777 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
779 // BinOpRI_RF - Instructions like "add reg, reg, imm".
780 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
781 SDNode opnode, Format f>
782 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
783 [(set typeinfo.RegClass:$dst, EFLAGS,
784 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
785 // BinOpRI_RFF - Instructions like "adc reg, reg, imm".
786 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
787 SDNode opnode, Format f>
788 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
789 [(set typeinfo.RegClass:$dst, EFLAGS,
790 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
791 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
793 // BinOpRI8 - Instructions like "add reg, reg, imm8".
794 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
795 Format f, dag outlist, list<dag> pattern,
796 InstrItinClass itin = IIC_BIN_NONMEM>
797 : ITy<opcode, f, typeinfo, outlist,
798 (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
799 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
801 let ImmT = Imm8; // Always 8-bit immediate.
804 // BinOpRI8_F - Instructions like "cmp reg, imm8".
805 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
806 SDPatternOperator opnode, Format f>
807 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
809 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
811 // BinOpRI8_RF - Instructions like "add reg, reg, imm8".
812 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
813 SDPatternOperator opnode, Format f>
814 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
815 [(set typeinfo.RegClass:$dst, EFLAGS,
816 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
818 // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
819 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
820 SDPatternOperator opnode, Format f>
821 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
822 [(set typeinfo.RegClass:$dst, EFLAGS,
823 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
824 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
826 // BinOpMR - Instructions like "add [mem], reg".
827 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
828 list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
829 : ITy<opcode, MRMDestMem, typeinfo,
830 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
831 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
832 Sched<[WriteALULd, WriteRMW]>;
834 // BinOpMR_RMW - Instructions like "add [mem], reg".
835 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
837 : BinOpMR<opcode, mnemonic, typeinfo,
838 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
841 // BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
842 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
844 : BinOpMR<opcode, mnemonic, typeinfo,
845 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
847 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
849 // BinOpMR_F - Instructions like "cmp [mem], reg".
850 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
851 SDPatternOperator opnode>
852 : BinOpMR<opcode, mnemonic, typeinfo,
853 [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
855 // BinOpMI - Instructions like "add [mem], imm".
856 class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
857 Format f, list<dag> pattern,
858 InstrItinClass itin = IIC_BIN_MEM>
859 : ITy<opcode, f, typeinfo,
860 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
861 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
862 Sched<[WriteALULd, WriteRMW]> {
863 let ImmT = typeinfo.ImmEncoding;
866 // BinOpMI_RMW - Instructions like "add [mem], imm".
867 class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
868 SDNode opnode, Format f>
869 : BinOpMI<opcode, mnemonic, typeinfo, f,
870 [(store (opnode (typeinfo.VT (load addr:$dst)),
871 typeinfo.ImmOperator:$src), addr:$dst),
873 // BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
874 class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
875 SDNode opnode, Format f>
876 : BinOpMI<opcode, mnemonic, typeinfo, f,
877 [(store (opnode (typeinfo.VT (load addr:$dst)),
878 typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
879 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
881 // BinOpMI_F - Instructions like "cmp [mem], imm".
882 class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
883 SDPatternOperator opnode, Format f>
884 : BinOpMI<opcode, mnemonic, typeinfo, f,
885 [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
886 typeinfo.ImmOperator:$src))]>;
888 // BinOpMI8 - Instructions like "add [mem], imm8".
889 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
890 Format f, list<dag> pattern,
891 InstrItinClass itin = IIC_BIN_MEM>
892 : ITy<0x82, f, typeinfo,
893 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
894 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
895 Sched<[WriteALULd, WriteRMW]> {
896 let ImmT = Imm8; // Always 8-bit immediate.
899 // BinOpMI8_RMW - Instructions like "add [mem], imm8".
900 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
901 SDPatternOperator opnode, Format f>
902 : BinOpMI8<mnemonic, typeinfo, f,
903 [(store (opnode (load addr:$dst),
904 typeinfo.Imm8Operator:$src), addr:$dst),
907 // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
908 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
909 SDPatternOperator opnode, Format f>
910 : BinOpMI8<mnemonic, typeinfo, f,
911 [(store (opnode (load addr:$dst),
912 typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
913 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
915 // BinOpMI8_F - Instructions like "cmp [mem], imm8".
916 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
917 SDPatternOperator opnode, Format f>
918 : BinOpMI8<mnemonic, typeinfo, f,
919 [(set EFLAGS, (opnode (load addr:$dst),
920 typeinfo.Imm8Operator:$src))]>;
922 // BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
923 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
924 Register areg, string operands,
925 InstrItinClass itin = IIC_BIN_NONMEM>
926 : ITy<opcode, RawFrm, typeinfo,
927 (outs), (ins typeinfo.ImmOperand:$src),
928 mnemonic, operands, [], itin>, Sched<[WriteALU]> {
929 let ImmT = typeinfo.ImmEncoding;
931 let Defs = [areg, EFLAGS];
932 let hasSideEffects = 0;
935 // BinOpAI_RFF - Instructions like "adc %eax, %eax, imm", that implicitly define
937 class BinOpAI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
938 Register areg, string operands>
939 : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
940 IIC_BIN_CARRY_NONMEM> {
941 let Uses = [areg, EFLAGS];
944 // BinOpAI_F - Instructions like "cmp %eax, %eax, imm", that imp-def EFLAGS.
945 class BinOpAI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
946 Register areg, string operands>
947 : BinOpAI<opcode, mnemonic, typeinfo, areg, operands> {
951 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
952 /// defined with "(set GPR:$dst, EFLAGS, (...".
954 /// It would be nice to get rid of the second and third argument here, but
955 /// tblgen can't handle dependent type references aggressively enough: PR8330
956 multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
957 string mnemonic, Format RegMRM, Format MemMRM,
958 SDNode opnodeflag, SDNode opnode,
959 bit CommutableRR, bit ConvertibleToThreeAddress> {
960 let Defs = [EFLAGS] in {
961 let Constraints = "$src1 = $dst" in {
962 let isCommutable = CommutableRR in {
963 def NAME#8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
964 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
965 def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
966 def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
967 def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
968 } // isConvertibleToThreeAddress
971 def NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
972 def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
973 def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
974 def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
976 def NAME#8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
977 def NAME#16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
978 def NAME#32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
979 def NAME#64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
981 def NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
983 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
984 // NOTE: These are order specific, we want the ri8 forms to be listed
985 // first so that they are slightly preferred to the ri forms.
986 def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
987 def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
988 def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
990 def NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
991 def NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
992 def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
994 } // Constraints = "$src1 = $dst"
996 let mayLoad = 1, mayStore = 1 in {
997 def NAME#8mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
998 def NAME#16mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
999 def NAME#32mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
1000 def NAME#64mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
1003 // NOTE: These are order specific, we want the mi8 forms to be listed
1004 // first so that they are slightly preferred to the mi forms.
1005 def NAME#16mi8 : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1006 def NAME#32mi8 : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1007 let Predicates = [In64BitMode] in
1008 def NAME#64mi8 : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1010 def NAME#8mi : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1011 def NAME#16mi : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1012 def NAME#32mi : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1013 let Predicates = [In64BitMode] in
1014 def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1016 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1017 // not in 64-bit mode.
1018 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1019 hasSideEffects = 0 in {
1020 let Constraints = "$src1 = $dst" in
1021 def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1022 let mayLoad = 1, mayStore = 1 in
1023 def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>;
1025 } // Defs = [EFLAGS]
1027 def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1028 "{$src, %al|al, $src}">;
1029 def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1030 "{$src, %ax|ax, $src}">;
1031 def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1032 "{$src, %eax|eax, $src}">;
1033 def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1034 "{$src, %rax|rax, $src}">;
1037 /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1038 /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1041 /// It would be nice to get rid of the second and third argument here, but
1042 /// tblgen can't handle dependent type references aggressively enough: PR8330
1043 multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1044 string mnemonic, Format RegMRM, Format MemMRM,
1045 SDNode opnode, bit CommutableRR,
1046 bit ConvertibleToThreeAddress> {
1047 let Uses = [EFLAGS], Defs = [EFLAGS] in {
1048 let Constraints = "$src1 = $dst" in {
1049 let isCommutable = CommutableRR in {
1050 def NAME#8rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1051 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1052 def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1053 def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1054 def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1055 } // isConvertibleToThreeAddress
1058 def NAME#8rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
1059 def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
1060 def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
1061 def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
1063 def NAME#8rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1064 def NAME#16rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1065 def NAME#32rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1066 def NAME#64rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1068 def NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1070 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1071 // NOTE: These are order specific, we want the ri8 forms to be listed
1072 // first so that they are slightly preferred to the ri forms.
1073 def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1074 def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1075 def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1077 def NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1078 def NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1079 def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1081 } // Constraints = "$src1 = $dst"
1083 def NAME#8mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1084 def NAME#16mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1085 def NAME#32mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1086 def NAME#64mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1088 // NOTE: These are order specific, we want the mi8 forms to be listed
1089 // first so that they are slightly preferred to the mi forms.
1090 def NAME#16mi8 : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1091 def NAME#32mi8 : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1092 let Predicates = [In64BitMode] in
1093 def NAME#64mi8 : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1095 def NAME#8mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1096 def NAME#16mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
1097 def NAME#32mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>;
1098 let Predicates = [In64BitMode] in
1099 def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1101 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1102 // not in 64-bit mode.
1103 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1104 hasSideEffects = 0 in {
1105 let Constraints = "$src1 = $dst" in
1106 def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1107 let mayLoad = 1, mayStore = 1 in
1108 def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
1110 } // Uses = [EFLAGS], Defs = [EFLAGS]
1112 def NAME#8i8 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi8 , AL,
1113 "{$src, %al|al, $src}">;
1114 def NAME#16i16 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi16, AX,
1115 "{$src, %ax|ax, $src}">;
1116 def NAME#32i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi32, EAX,
1117 "{$src, %eax|eax, $src}">;
1118 def NAME#64i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi64, RAX,
1119 "{$src, %rax|rax, $src}">;
1122 /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1123 /// defined with "(set EFLAGS, (...". It would be really nice to find a way
1124 /// to factor this with the other ArithBinOp_*.
1126 multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1127 string mnemonic, Format RegMRM, Format MemMRM,
1129 bit CommutableRR, bit ConvertibleToThreeAddress> {
1130 let Defs = [EFLAGS] in {
1131 let isCommutable = CommutableRR in {
1132 def NAME#8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1133 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1134 def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1135 def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1136 def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1140 def NAME#8rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
1141 def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
1142 def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
1143 def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
1145 def NAME#8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1146 def NAME#16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1147 def NAME#32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1148 def NAME#64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1150 def NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1152 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1153 // NOTE: These are order specific, we want the ri8 forms to be listed
1154 // first so that they are slightly preferred to the ri forms.
1155 def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1156 def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1157 def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1159 def NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1160 def NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1161 def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1164 def NAME#8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1165 def NAME#16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1166 def NAME#32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1167 def NAME#64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1169 // NOTE: These are order specific, we want the mi8 forms to be listed
1170 // first so that they are slightly preferred to the mi forms.
1171 def NAME#16mi8 : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1172 def NAME#32mi8 : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1173 let Predicates = [In64BitMode] in
1174 def NAME#64mi8 : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1176 def NAME#8mi : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1177 def NAME#16mi : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1178 def NAME#32mi : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1179 let Predicates = [In64BitMode] in
1180 def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1182 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1183 // not in 64-bit mode.
1184 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1185 hasSideEffects = 0 in {
1186 def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1188 def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>;
1190 } // Defs = [EFLAGS]
1192 def NAME#8i8 : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL,
1193 "{$src, %al|al, $src}">;
1194 def NAME#16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX,
1195 "{$src, %ax|ax, $src}">;
1196 def NAME#32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX,
1197 "{$src, %eax|eax, $src}">;
1198 def NAME#64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX,
1199 "{$src, %rax|rax, $src}">;
1203 defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1204 X86and_flag, and, 1, 0>;
1205 defm OR : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1206 X86or_flag, or, 1, 0>;
1207 defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1208 X86xor_flag, xor, 1, 0>;
1209 defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1210 X86add_flag, add, 1, 1>;
1211 let isCompare = 1 in {
1212 defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1213 X86sub_flag, sub, 0, 0>;
1217 defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1219 defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1222 let isCompare = 1 in {
1223 defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1227 //===----------------------------------------------------------------------===//
1228 // Semantically, test instructions are similar like AND, except they don't
1229 // generate a result. From an encoding perspective, they are very different:
1230 // they don't have all the usual imm8 and REV forms, and are encoded into a
1232 def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1233 (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1235 let isCompare = 1 in {
1236 let Defs = [EFLAGS] in {
1237 let isCommutable = 1 in {
1238 def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat>;
1239 def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat>;
1240 def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat>;
1241 def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat>;
1244 def TEST8mr : BinOpMR_F<0x84, "test", Xi8 , X86testpat>;
1245 def TEST16mr : BinOpMR_F<0x84, "test", Xi16, X86testpat>;
1246 def TEST32mr : BinOpMR_F<0x84, "test", Xi32, X86testpat>;
1247 def TEST64mr : BinOpMR_F<0x84, "test", Xi64, X86testpat>;
1249 def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1250 def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1251 def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1252 let Predicates = [In64BitMode] in
1253 def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1255 def TEST8mi : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1256 def TEST16mi : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1257 def TEST32mi : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1258 let Predicates = [In64BitMode] in
1259 def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1261 // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1262 // register class is constrained to GR8_NOREX. This pseudo is explicitly
1263 // marked side-effect free, since it doesn't have an isel pattern like
1264 // other test instructions.
1265 let isPseudo = 1, hasSideEffects = 0 in
1266 def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1267 "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1268 } // Defs = [EFLAGS]
1270 def TEST8i8 : BinOpAI_F<0xA8, "test", Xi8 , AL,
1271 "{$src, %al|al, $src}">;
1272 def TEST16i16 : BinOpAI_F<0xA8, "test", Xi16, AX,
1273 "{$src, %ax|ax, $src}">;
1274 def TEST32i32 : BinOpAI_F<0xA8, "test", Xi32, EAX,
1275 "{$src, %eax|eax, $src}">;
1276 def TEST64i32 : BinOpAI_F<0xA8, "test", Xi64, RAX,
1277 "{$src, %rax|rax, $src}">;
1280 //===----------------------------------------------------------------------===//
1283 multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1285 def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1286 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1287 [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1288 IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1289 def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1290 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1291 [(set RC:$dst, EFLAGS,
1292 (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1293 Sched<[WriteALULd, ReadAfterLd]>;
1296 let Predicates = [HasBMI], Defs = [EFLAGS] in {
1297 defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1298 defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1301 let Predicates = [HasBMI] in {
1302 def : Pat<(and (not GR32:$src1), GR32:$src2),
1303 (ANDN32rr GR32:$src1, GR32:$src2)>;
1304 def : Pat<(and (not GR64:$src1), GR64:$src2),
1305 (ANDN64rr GR64:$src1, GR64:$src2)>;
1306 def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1307 (ANDN32rm GR32:$src1, addr:$src2)>;
1308 def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1309 (ANDN64rm GR64:$src1, addr:$src2)>;
1312 //===----------------------------------------------------------------------===//
1315 multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1316 let hasSideEffects = 0 in {
1317 let isCommutable = 1 in
1318 def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1319 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1320 [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1323 def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1324 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1325 [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1329 let Predicates = [HasBMI2] in {
1331 defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1333 defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1336 //===----------------------------------------------------------------------===//
1339 let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1340 Constraints = "$src0 = $dst", AddedComplexity = 10 in {
1341 let SchedRW = [WriteALU] in {
1342 def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1343 (ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1344 [(set GR32:$dst, EFLAGS,
1345 (X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
1346 IIC_BIN_CARRY_NONMEM>, T8PD;
1347 def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1348 (ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1349 [(set GR64:$dst, EFLAGS,
1350 (X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
1351 IIC_BIN_CARRY_NONMEM>, T8PD;
1354 let mayLoad = 1, SchedRW = [WriteALULd] in {
1355 def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1356 (ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1357 [(set GR32:$dst, EFLAGS,
1358 (X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
1359 IIC_BIN_CARRY_MEM>, T8PD;
1361 def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1362 (ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1363 [(set GR64:$dst, EFLAGS,
1364 (X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
1365 IIC_BIN_CARRY_MEM>, T8PD;
1369 //===----------------------------------------------------------------------===//
1372 let Predicates = [HasADX], hasSideEffects = 0, Defs = [EFLAGS],
1373 Uses = [EFLAGS] in {
1374 let SchedRW = [WriteALU] in {
1375 def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1376 "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1378 def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1379 "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1382 let mayLoad = 1, SchedRW = [WriteALULd] in {
1383 def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1384 "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1386 def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1387 "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;