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 i32mem:$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 i32mem:$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>;
110 let hasSideEffects = 0 in {
112 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
113 def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", [],
114 IIC_IMUL8>, Sched<[WriteIMul]>;
116 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
117 def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", [],
118 IIC_IMUL16_RR>, OpSize16, Sched<[WriteIMul]>;
119 // EAX,EDX = EAX*GR32
120 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
121 def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", [],
122 IIC_IMUL32_RR>, OpSize32, Sched<[WriteIMul]>;
123 // RAX,RDX = RAX*GR64
124 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
125 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
126 IIC_IMUL64_RR>, Sched<[WriteIMul]>;
130 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
131 def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
132 "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
133 // AX,DX = AX*[mem16]
134 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
135 def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
136 "imul{w}\t$src", [], IIC_IMUL16_MEM>, OpSize16,
137 SchedLoadReg<WriteIMulLd>;
138 // EAX,EDX = EAX*[mem32]
139 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
140 def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
141 "imul{l}\t$src", [], IIC_IMUL32_MEM>, OpSize32,
142 SchedLoadReg<WriteIMulLd>;
143 // RAX,RDX = RAX*[mem64]
144 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
145 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
146 "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>;
151 let Defs = [EFLAGS] in {
152 let Constraints = "$src1 = $dst" in {
154 let isCommutable = 1, SchedRW = [WriteIMul] in {
155 // X = IMUL Y, Z --> X = IMUL Z, Y
156 // Register-Register Signed Integer Multiply
157 def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
158 "imul{w}\t{$src2, $dst|$dst, $src2}",
159 [(set GR16:$dst, EFLAGS,
160 (X86smul_flag GR16:$src1, GR16:$src2))], IIC_IMUL16_RR>,
162 def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
163 "imul{l}\t{$src2, $dst|$dst, $src2}",
164 [(set GR32:$dst, EFLAGS,
165 (X86smul_flag GR32:$src1, GR32:$src2))], IIC_IMUL32_RR>,
167 def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
168 (ins GR64:$src1, GR64:$src2),
169 "imul{q}\t{$src2, $dst|$dst, $src2}",
170 [(set GR64:$dst, EFLAGS,
171 (X86smul_flag GR64:$src1, GR64:$src2))], IIC_IMUL64_RR>,
173 } // isCommutable, SchedRW
175 // Register-Memory Signed Integer Multiply
176 let SchedRW = [WriteIMulLd, ReadAfterLd] in {
177 def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
178 (ins GR16:$src1, i16mem:$src2),
179 "imul{w}\t{$src2, $dst|$dst, $src2}",
180 [(set GR16:$dst, EFLAGS,
181 (X86smul_flag GR16:$src1, (load addr:$src2)))],
184 def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
185 (ins GR32:$src1, i32mem:$src2),
186 "imul{l}\t{$src2, $dst|$dst, $src2}",
187 [(set GR32:$dst, EFLAGS,
188 (X86smul_flag GR32:$src1, (load addr:$src2)))],
191 def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
192 (ins GR64:$src1, i64mem:$src2),
193 "imul{q}\t{$src2, $dst|$dst, $src2}",
194 [(set GR64:$dst, EFLAGS,
195 (X86smul_flag GR64:$src1, (load addr:$src2)))],
199 } // Constraints = "$src1 = $dst"
203 // Surprisingly enough, these are not two address instructions!
204 let Defs = [EFLAGS] in {
205 let SchedRW = [WriteIMul] in {
206 // Register-Integer Signed Integer Multiply
207 def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16
208 (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
209 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
210 [(set GR16:$dst, EFLAGS,
211 (X86smul_flag GR16:$src1, imm:$src2))],
212 IIC_IMUL16_RRI>, OpSize16;
213 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // GR16 = GR16*I8
214 (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
215 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
216 [(set GR16:$dst, EFLAGS,
217 (X86smul_flag GR16:$src1, i16immSExt8:$src2))],
218 IIC_IMUL16_RRI>, OpSize16;
219 def IMUL32rri : Ii32<0x69, MRMSrcReg, // GR32 = GR32*I32
220 (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
221 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
222 [(set GR32:$dst, EFLAGS,
223 (X86smul_flag GR32:$src1, imm:$src2))],
224 IIC_IMUL32_RRI>, OpSize32;
225 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8
226 (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
227 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
228 [(set GR32:$dst, EFLAGS,
229 (X86smul_flag GR32:$src1, i32immSExt8:$src2))],
230 IIC_IMUL32_RRI>, OpSize32;
231 def IMUL64rri32 : RIi32S<0x69, MRMSrcReg, // GR64 = GR64*I32
232 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
233 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
234 [(set GR64:$dst, EFLAGS,
235 (X86smul_flag GR64:$src1, i64immSExt32:$src2))],
237 def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
238 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
239 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
240 [(set GR64:$dst, EFLAGS,
241 (X86smul_flag GR64:$src1, i64immSExt8:$src2))],
245 // Memory-Integer Signed Integer Multiply
246 let SchedRW = [WriteIMulLd] in {
247 def IMUL16rmi : Ii16<0x69, MRMSrcMem, // GR16 = [mem16]*I16
248 (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
249 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
250 [(set GR16:$dst, EFLAGS,
251 (X86smul_flag (load addr:$src1), imm:$src2))],
254 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // GR16 = [mem16]*I8
255 (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
256 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
257 [(set GR16:$dst, EFLAGS,
258 (X86smul_flag (load addr:$src1),
259 i16immSExt8:$src2))], IIC_IMUL16_RMI>,
261 def IMUL32rmi : Ii32<0x69, MRMSrcMem, // GR32 = [mem32]*I32
262 (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
263 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
264 [(set GR32:$dst, EFLAGS,
265 (X86smul_flag (load addr:$src1), imm:$src2))],
266 IIC_IMUL32_RMI>, OpSize32;
267 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8
268 (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
269 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
270 [(set GR32:$dst, EFLAGS,
271 (X86smul_flag (load addr:$src1),
272 i32immSExt8:$src2))],
273 IIC_IMUL32_RMI>, OpSize32;
274 def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem, // GR64 = [mem64]*I32
275 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
276 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
277 [(set GR64:$dst, EFLAGS,
278 (X86smul_flag (load addr:$src1),
279 i64immSExt32:$src2))],
281 def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
282 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
283 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
284 [(set GR64:$dst, EFLAGS,
285 (X86smul_flag (load addr:$src1),
286 i64immSExt8:$src2))],
294 // unsigned division/remainder
295 let hasSideEffects = 1 in { // so that we don't speculatively execute
296 let SchedRW = [WriteIDiv] in {
297 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
298 def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
299 "div{b}\t$src", [], IIC_DIV8_REG>;
300 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
301 def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
302 "div{w}\t$src", [], IIC_DIV16>, OpSize16;
303 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
304 def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
305 "div{l}\t$src", [], IIC_DIV32>, OpSize32;
306 // RDX:RAX/r64 = RAX,RDX
307 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
308 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
309 "div{q}\t$src", [], IIC_DIV64>;
313 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
314 def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
315 "div{b}\t$src", [], IIC_DIV8_MEM>,
316 SchedLoadReg<WriteIDivLd>;
317 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
318 def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
319 "div{w}\t$src", [], IIC_DIV16>, OpSize16,
320 SchedLoadReg<WriteIDivLd>;
321 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
322 def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
323 "div{l}\t$src", [], IIC_DIV32>,
324 SchedLoadReg<WriteIDivLd>, OpSize32;
325 // RDX:RAX/[mem64] = RAX,RDX
326 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
327 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
328 "div{q}\t$src", [], IIC_DIV64>,
329 SchedLoadReg<WriteIDivLd>;
332 // Signed division/remainder.
333 let SchedRW = [WriteIDiv] in {
334 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
335 def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
336 "idiv{b}\t$src", [], IIC_IDIV8>;
337 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
338 def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
339 "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16;
340 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
341 def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
342 "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32;
343 // RDX:RAX/r64 = RAX,RDX
344 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
345 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
346 "idiv{q}\t$src", [], IIC_IDIV64>;
350 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
351 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
352 "idiv{b}\t$src", [], IIC_IDIV8>,
353 SchedLoadReg<WriteIDivLd>;
354 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
355 def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
356 "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16,
357 SchedLoadReg<WriteIDivLd>;
358 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
359 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
360 "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32,
361 SchedLoadReg<WriteIDivLd>;
362 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
363 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
364 "idiv{q}\t$src", [], IIC_IDIV64>,
365 SchedLoadReg<WriteIDivLd>;
367 } // hasSideEffects = 0
369 //===----------------------------------------------------------------------===//
370 // Two address Instructions.
373 // unary instructions
374 let CodeSize = 2 in {
375 let Defs = [EFLAGS] in {
376 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
377 def NEG8r : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
379 [(set GR8:$dst, (ineg GR8:$src1)),
380 (implicit EFLAGS)], IIC_UNARY_REG>;
381 def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
383 [(set GR16:$dst, (ineg GR16:$src1)),
384 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize16;
385 def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
387 [(set GR32:$dst, (ineg GR32:$src1)),
388 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize32;
389 def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
390 [(set GR64:$dst, (ineg GR64:$src1)),
391 (implicit EFLAGS)], IIC_UNARY_REG>;
392 } // Constraints = "$src1 = $dst", SchedRW
394 // Read-modify-write negate.
395 let SchedRW = [WriteALULd, WriteRMW] in {
396 def NEG8m : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
398 [(store (ineg (loadi8 addr:$dst)), addr:$dst),
399 (implicit EFLAGS)], IIC_UNARY_MEM>;
400 def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
402 [(store (ineg (loadi16 addr:$dst)), addr:$dst),
403 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize16;
404 def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
406 [(store (ineg (loadi32 addr:$dst)), addr:$dst),
407 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize32;
408 def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
409 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
410 (implicit EFLAGS)], IIC_UNARY_MEM>;
415 // Note: NOT does not set EFLAGS!
417 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
418 // Match xor -1 to not. Favors these over a move imm + xor to save code size.
419 let AddedComplexity = 15 in {
420 def NOT8r : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
422 [(set GR8:$dst, (not GR8:$src1))], IIC_UNARY_REG>;
423 def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
425 [(set GR16:$dst, (not GR16:$src1))], IIC_UNARY_REG>, OpSize16;
426 def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
428 [(set GR32:$dst, (not GR32:$src1))], IIC_UNARY_REG>, OpSize32;
429 def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
430 [(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
432 } // Constraints = "$src1 = $dst", SchedRW
434 let SchedRW = [WriteALULd, WriteRMW] in {
435 def NOT8m : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
437 [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
438 def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
440 [(store (not (loadi16 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
442 def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
444 [(store (not (loadi32 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
446 def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
447 [(store (not (loadi64 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
451 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
452 let Defs = [EFLAGS] in {
453 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
455 def INC8r : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
457 [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))],
460 let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
461 def INC16r : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
462 "inc{w}\t$dst", [], IIC_UNARY_REG>,
463 OpSize16, Requires<[Not64BitMode]>;
464 def INC32r : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
465 "inc{l}\t$dst", [], IIC_UNARY_REG>,
466 OpSize32, Requires<[Not64BitMode]>;
467 def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
468 [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
470 } // isConvertibleToThreeAddress = 1, CodeSize = 1
473 // In 64-bit mode, single byte INC and DEC cannot be encoded.
474 let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
475 // Can transform into LEA.
476 def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
477 "inc{w}\t$dst", [], IIC_UNARY_REG>, OpSize16;
478 def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
479 "inc{l}\t$dst", [], IIC_UNARY_REG>, OpSize32;
480 def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
481 "dec{w}\t$dst", [], IIC_UNARY_REG>, OpSize16;
482 def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
483 "dec{l}\t$dst", [], IIC_UNARY_REG>, OpSize32;
484 } // isConvertibleToThreeAddress = 1, CodeSize = 2
486 } // Constraints = "$src1 = $dst", SchedRW
488 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
489 def INC8m : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
490 [(store (add (loadi8 addr:$dst), 1), addr:$dst),
491 (implicit EFLAGS)], IIC_UNARY_MEM>;
492 def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
493 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
494 (implicit EFLAGS)], IIC_UNARY_MEM>,
495 OpSize16, Requires<[Not64BitMode]>;
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>,
499 OpSize32, Requires<[Not64BitMode]>;
500 def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
501 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
502 (implicit EFLAGS)], IIC_UNARY_MEM>;
504 // These are duplicates of their 32-bit counterparts. Only needed so X86 knows
505 // how to unfold them.
506 // FIXME: What is this for??
507 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
508 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
509 (implicit EFLAGS)], IIC_UNARY_MEM>,
510 OpSize16, Requires<[In64BitMode]>;
511 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
512 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
513 (implicit EFLAGS)], IIC_UNARY_MEM>,
514 OpSize32, Requires<[In64BitMode]>;
515 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
516 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
517 (implicit EFLAGS)], IIC_UNARY_MEM>,
518 OpSize16, Requires<[In64BitMode]>;
519 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
520 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
521 (implicit EFLAGS)], IIC_UNARY_MEM>,
522 OpSize32, Requires<[In64BitMode]>;
523 } // CodeSize = 2, SchedRW
525 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
527 def DEC8r : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
529 [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
531 let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
532 def DEC16r : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
533 "dec{w}\t$dst", [], IIC_UNARY_REG>,
534 OpSize16, Requires<[Not64BitMode]>;
535 def DEC32r : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
536 "dec{l}\t$dst", [], IIC_UNARY_REG>,
537 OpSize32, Requires<[Not64BitMode]>;
538 def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
539 [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
542 } // Constraints = "$src1 = $dst", SchedRW
545 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
546 def DEC8m : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
547 [(store (add (loadi8 addr:$dst), -1), addr:$dst),
548 (implicit EFLAGS)], IIC_UNARY_MEM>;
549 def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
550 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
551 (implicit EFLAGS)], IIC_UNARY_MEM>,
552 OpSize16, Requires<[Not64BitMode]>;
553 def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
554 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
555 (implicit EFLAGS)], IIC_UNARY_MEM>,
556 OpSize32, Requires<[Not64BitMode]>;
557 def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
558 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
559 (implicit EFLAGS)], IIC_UNARY_MEM>;
560 } // CodeSize = 2, SchedRW
563 let Predicates = [Not64BitMode] in {
564 def : Pat<(X86inc_flag GR16:$src1), (INC16r GR16:$src1)>;
565 def : Pat<(X86inc_flag GR32:$src1), (INC32r GR32:$src1)>;
566 def : Pat<(X86dec_flag GR16:$src1), (DEC16r GR16:$src1)>;
567 def : Pat<(X86dec_flag GR32:$src1), (DEC32r GR32:$src1)>;
570 let Predicates = [In64BitMode] in {
571 def : Pat<(X86inc_flag GR16:$src1), (INC64_16r GR16:$src1)>;
572 def : Pat<(X86inc_flag GR32:$src1), (INC64_32r GR32:$src1)>;
573 def : Pat<(X86dec_flag GR16:$src1), (DEC64_16r GR16:$src1)>;
574 def : Pat<(X86dec_flag GR32:$src1), (DEC64_32r GR32:$src1)>;
577 /// X86TypeInfo - This is a bunch of information that describes relevant X86
578 /// information about value types. For example, it can tell you what the
579 /// register class and preferred load to use.
580 class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
581 PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
582 Operand immoperand, SDPatternOperator immoperator,
583 Operand imm8operand, SDPatternOperator imm8operator,
584 bit hasOddOpcode, OperandSize opSize,
585 bit hasREX_WPrefix> {
586 /// VT - This is the value type itself.
589 /// InstrSuffix - This is the suffix used on instructions with this type. For
590 /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
591 string InstrSuffix = instrsuffix;
593 /// RegClass - This is the register class associated with this type. For
594 /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
595 RegisterClass RegClass = regclass;
597 /// LoadNode - This is the load node associated with this type. For
598 /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
599 PatFrag LoadNode = loadnode;
601 /// MemOperand - This is the memory operand associated with this type. For
602 /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
603 X86MemOperand MemOperand = memoperand;
605 /// ImmEncoding - This is the encoding of an immediate of this type. For
606 /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32. Note that i64 -> Imm32
607 /// since the immediate fields of i64 instructions is a 32-bit sign extended
609 ImmType ImmEncoding = immkind;
611 /// ImmOperand - This is the operand kind of an immediate of this type. For
612 /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm. Note that i64 ->
613 /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
615 Operand ImmOperand = immoperand;
617 /// ImmOperator - This is the operator that should be used to match an
618 /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
619 SDPatternOperator ImmOperator = immoperator;
621 /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
622 /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm. This is
623 /// only used for instructions that have a sign-extended imm8 field form.
624 Operand Imm8Operand = imm8operand;
626 /// Imm8Operator - This is the operator that should be used to match an 8-bit
627 /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
628 SDPatternOperator Imm8Operator = imm8operator;
630 /// HasOddOpcode - This bit is true if the instruction should have an odd (as
631 /// opposed to even) opcode. Operations on i8 are usually even, operations on
632 /// other datatypes are odd.
633 bit HasOddOpcode = hasOddOpcode;
635 /// OpSize - Selects whether the instruction needs a 0x66 prefix based on
636 /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this
637 /// to Opsize16. i32 sets this to OpSize32.
638 OperandSize OpSize = opSize;
640 /// HasREX_WPrefix - This bit is set to true if the instruction should have
641 /// the 0x40 REX prefix. This is set for i64 types.
642 bit HasREX_WPrefix = hasREX_WPrefix;
645 def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
648 def Xi8 : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
649 Imm8 , i8imm , imm, i8imm , invalid_node,
651 def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
652 Imm16, i16imm, imm, i16i8imm, i16immSExt8,
654 def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
655 Imm32, i32imm, imm, i32i8imm, i32immSExt8,
657 def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
658 Imm32S, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8,
661 /// ITy - This instruction base class takes the type info for the instruction.
663 /// 1. Concatenates together the instruction mnemonic with the appropriate
664 /// suffix letter, a tab, and the arguments.
665 /// 2. Infers whether the instruction should have a 0x66 prefix byte.
666 /// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
667 /// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
668 /// or 1 (for i16,i32,i64 operations).
669 class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
670 string mnemonic, string args, list<dag> pattern,
671 InstrItinClass itin = IIC_BIN_NONMEM>
672 : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
673 opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
675 !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
678 // Infer instruction prefixes from type info.
679 let OpSize = typeinfo.OpSize;
680 let hasREX_WPrefix = typeinfo.HasREX_WPrefix;
683 // BinOpRR - Instructions like "add reg, reg, reg".
684 class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
685 dag outlist, list<dag> pattern, InstrItinClass itin,
686 Format f = MRMDestReg>
687 : ITy<opcode, f, typeinfo, outlist,
688 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
689 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
692 // BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
693 // just a EFLAGS as a result.
694 class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
695 SDPatternOperator opnode, Format f = MRMDestReg>
696 : BinOpRR<opcode, mnemonic, typeinfo, (outs),
698 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
701 // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
702 // both a regclass and EFLAGS as a result.
703 class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
705 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
706 [(set typeinfo.RegClass:$dst, EFLAGS,
707 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
710 // BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
711 // both a regclass and EFLAGS as a result, and has EFLAGS as input.
712 class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
714 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
715 [(set typeinfo.RegClass:$dst, EFLAGS,
716 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
717 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
719 // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
720 class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
721 InstrItinClass itin = IIC_BIN_NONMEM>
722 : ITy<opcode, MRMSrcReg, typeinfo,
723 (outs typeinfo.RegClass:$dst),
724 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
725 mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
727 // The disassembler should know about this, but not the asmparser.
728 let isCodeGenOnly = 1;
729 let ForceDisassemble = 1;
730 let hasSideEffects = 0;
733 // BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
734 class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
735 : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
737 // BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
738 class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
739 : ITy<opcode, MRMSrcReg, typeinfo, (outs),
740 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
741 mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
743 // The disassembler should know about this, but not the asmparser.
744 let isCodeGenOnly = 1;
745 let ForceDisassemble = 1;
746 let hasSideEffects = 0;
749 // BinOpRM - Instructions like "add reg, reg, [mem]".
750 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
751 dag outlist, list<dag> pattern,
752 InstrItinClass itin = IIC_BIN_MEM>
753 : ITy<opcode, MRMSrcMem, typeinfo, outlist,
754 (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
755 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
756 Sched<[WriteALULd, ReadAfterLd]>;
758 // BinOpRM_R - Instructions like "add reg, reg, [mem]".
759 class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
761 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
762 [(set typeinfo.RegClass:$dst,
763 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
765 // BinOpRM_F - Instructions like "cmp reg, [mem]".
766 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
767 SDPatternOperator opnode>
768 : BinOpRM<opcode, mnemonic, typeinfo, (outs),
770 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
772 // BinOpRM_RF - Instructions like "add reg, reg, [mem]".
773 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
775 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
776 [(set typeinfo.RegClass:$dst, EFLAGS,
777 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
779 // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
780 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
782 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
783 [(set typeinfo.RegClass:$dst, EFLAGS,
784 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
785 EFLAGS))], IIC_BIN_CARRY_MEM>;
787 // BinOpRI - Instructions like "add reg, reg, imm".
788 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
789 Format f, dag outlist, list<dag> pattern,
790 InstrItinClass itin = IIC_BIN_NONMEM>
791 : ITy<opcode, f, typeinfo, outlist,
792 (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
793 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
795 let ImmT = typeinfo.ImmEncoding;
798 // BinOpRI_F - Instructions like "cmp reg, imm".
799 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
800 SDPatternOperator opnode, Format f>
801 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
803 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
805 // BinOpRI_RF - Instructions like "add reg, reg, imm".
806 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
807 SDNode opnode, Format f>
808 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
809 [(set typeinfo.RegClass:$dst, EFLAGS,
810 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
811 // BinOpRI_RFF - Instructions like "adc reg, reg, imm".
812 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
813 SDNode opnode, Format f>
814 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
815 [(set typeinfo.RegClass:$dst, EFLAGS,
816 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
817 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
819 // BinOpRI8 - Instructions like "add reg, reg, imm8".
820 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
821 Format f, dag outlist, list<dag> pattern,
822 InstrItinClass itin = IIC_BIN_NONMEM>
823 : ITy<opcode, f, typeinfo, outlist,
824 (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
825 mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
827 let ImmT = Imm8; // Always 8-bit immediate.
830 // BinOpRI8_F - Instructions like "cmp reg, imm8".
831 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
832 SDPatternOperator opnode, Format f>
833 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
835 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
837 // BinOpRI8_RF - Instructions like "add reg, reg, imm8".
838 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
839 SDPatternOperator opnode, Format f>
840 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
841 [(set typeinfo.RegClass:$dst, EFLAGS,
842 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
844 // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
845 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
846 SDPatternOperator opnode, Format f>
847 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
848 [(set typeinfo.RegClass:$dst, EFLAGS,
849 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
850 EFLAGS))], IIC_BIN_CARRY_NONMEM>;
852 // BinOpMR - Instructions like "add [mem], reg".
853 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
854 list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
855 : ITy<opcode, MRMDestMem, typeinfo,
856 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
857 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
858 Sched<[WriteALULd, WriteRMW]>;
860 // BinOpMR_RMW - Instructions like "add [mem], reg".
861 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
863 : BinOpMR<opcode, mnemonic, typeinfo,
864 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
867 // BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
868 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
870 : BinOpMR<opcode, mnemonic, typeinfo,
871 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
873 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
875 // BinOpMR_F - Instructions like "cmp [mem], reg".
876 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
878 : BinOpMR<opcode, mnemonic, typeinfo,
879 [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
881 // BinOpMI - Instructions like "add [mem], imm".
882 class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
883 Format f, list<dag> pattern,
884 InstrItinClass itin = IIC_BIN_MEM>
885 : ITy<opcode, f, typeinfo,
886 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
887 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
888 Sched<[WriteALULd, WriteRMW]> {
889 let ImmT = typeinfo.ImmEncoding;
892 // BinOpMI_RMW - Instructions like "add [mem], imm".
893 class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
894 SDNode opnode, Format f>
895 : BinOpMI<opcode, mnemonic, typeinfo, f,
896 [(store (opnode (typeinfo.VT (load addr:$dst)),
897 typeinfo.ImmOperator:$src), addr:$dst),
899 // BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
900 class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
901 SDNode opnode, Format f>
902 : BinOpMI<opcode, mnemonic, typeinfo, f,
903 [(store (opnode (typeinfo.VT (load addr:$dst)),
904 typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
905 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
907 // BinOpMI_F - Instructions like "cmp [mem], imm".
908 class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
909 SDPatternOperator opnode, Format f>
910 : BinOpMI<opcode, mnemonic, typeinfo, f,
911 [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
912 typeinfo.ImmOperator:$src))]>;
914 // BinOpMI8 - Instructions like "add [mem], imm8".
915 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
916 Format f, list<dag> pattern,
917 InstrItinClass itin = IIC_BIN_MEM>
918 : ITy<0x82, f, typeinfo,
919 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
920 mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
921 Sched<[WriteALULd, WriteRMW]> {
922 let ImmT = Imm8; // Always 8-bit immediate.
925 // BinOpMI8_RMW - Instructions like "add [mem], imm8".
926 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
927 SDPatternOperator opnode, Format f>
928 : BinOpMI8<mnemonic, typeinfo, f,
929 [(store (opnode (load addr:$dst),
930 typeinfo.Imm8Operator:$src), addr:$dst),
933 // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
934 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
935 SDPatternOperator opnode, Format f>
936 : BinOpMI8<mnemonic, typeinfo, f,
937 [(store (opnode (load addr:$dst),
938 typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
939 (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
941 // BinOpMI8_F - Instructions like "cmp [mem], imm8".
942 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
943 SDPatternOperator opnode, Format f>
944 : BinOpMI8<mnemonic, typeinfo, f,
945 [(set EFLAGS, (opnode (load addr:$dst),
946 typeinfo.Imm8Operator:$src))]>;
948 // BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
949 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
950 Register areg, string operands,
951 InstrItinClass itin = IIC_BIN_NONMEM>
952 : ITy<opcode, RawFrm, typeinfo,
953 (outs), (ins typeinfo.ImmOperand:$src),
954 mnemonic, operands, [], itin>, Sched<[WriteALU]> {
955 let ImmT = typeinfo.ImmEncoding;
957 let Defs = [areg, EFLAGS];
958 let hasSideEffects = 0;
961 // BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
963 class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
964 Register areg, string operands>
965 : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
966 IIC_BIN_CARRY_NONMEM> {
967 let Uses = [areg, EFLAGS];
970 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
971 /// defined with "(set GPR:$dst, EFLAGS, (...".
973 /// It would be nice to get rid of the second and third argument here, but
974 /// tblgen can't handle dependent type references aggressively enough: PR8330
975 multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
976 string mnemonic, Format RegMRM, Format MemMRM,
977 SDNode opnodeflag, SDNode opnode,
978 bit CommutableRR, bit ConvertibleToThreeAddress> {
979 let Defs = [EFLAGS] in {
980 let Constraints = "$src1 = $dst" in {
981 let isCommutable = CommutableRR in {
982 def NAME#8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
983 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
984 def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
985 def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
986 def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
987 } // isConvertibleToThreeAddress
990 def NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
991 def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
992 def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
993 def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
995 def NAME#8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
996 def NAME#16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
997 def NAME#32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
998 def NAME#64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
1000 def NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
1002 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1003 // NOTE: These are order specific, we want the ri8 forms to be listed
1004 // first so that they are slightly preferred to the ri forms.
1005 def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
1006 def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
1007 def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
1009 def NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
1010 def NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
1011 def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
1013 } // Constraints = "$src1 = $dst"
1015 def NAME#8mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
1016 def NAME#16mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
1017 def NAME#32mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
1018 def NAME#64mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
1020 // NOTE: These are order specific, we want the mi8 forms to be listed
1021 // first so that they are slightly preferred to the mi forms.
1022 def NAME#16mi8 : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1023 def NAME#32mi8 : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1024 def NAME#64mi8 : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1026 def NAME#8mi : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1027 def NAME#16mi : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1028 def NAME#32mi : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1029 def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1031 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1032 // not in 64-bit mode.
1033 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1034 hasSideEffects = 0 in {
1035 let Constraints = "$src1 = $dst" in
1036 def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1037 let mayLoad = 1, mayStore = 1 in
1038 def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>;
1040 } // Defs = [EFLAGS]
1042 def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1043 "{$src, %al|al, $src}">;
1044 def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1045 "{$src, %ax|ax, $src}">;
1046 def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1047 "{$src, %eax|eax, $src}">;
1048 def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1049 "{$src, %rax|rax, $src}">;
1052 /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1053 /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1056 /// It would be nice to get rid of the second and third argument here, but
1057 /// tblgen can't handle dependent type references aggressively enough: PR8330
1058 multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1059 string mnemonic, Format RegMRM, Format MemMRM,
1060 SDNode opnode, bit CommutableRR,
1061 bit ConvertibleToThreeAddress> {
1062 let Uses = [EFLAGS], Defs = [EFLAGS] in {
1063 let Constraints = "$src1 = $dst" in {
1064 let isCommutable = CommutableRR in {
1065 def NAME#8rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1066 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1067 def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1068 def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1069 def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1070 } // isConvertibleToThreeAddress
1073 def NAME#8rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
1074 def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
1075 def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
1076 def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
1078 def NAME#8rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1079 def NAME#16rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1080 def NAME#32rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1081 def NAME#64rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1083 def NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1085 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1086 // NOTE: These are order specific, we want the ri8 forms to be listed
1087 // first so that they are slightly preferred to the ri forms.
1088 def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1089 def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1090 def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1092 def NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1093 def NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1094 def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1096 } // Constraints = "$src1 = $dst"
1098 def NAME#8mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1099 def NAME#16mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1100 def NAME#32mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1101 def NAME#64mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1103 // NOTE: These are order specific, we want the mi8 forms to be listed
1104 // first so that they are slightly preferred to the mi forms.
1105 def NAME#16mi8 : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1106 def NAME#32mi8 : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1107 def NAME#64mi8 : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1109 def NAME#8mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1110 def NAME#16mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
1111 def NAME#32mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>;
1112 def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1114 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1115 // not in 64-bit mode.
1116 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1117 hasSideEffects = 0 in {
1118 let Constraints = "$src1 = $dst" in
1119 def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1120 let mayLoad = 1, mayStore = 1 in
1121 def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
1123 } // Uses = [EFLAGS], Defs = [EFLAGS]
1125 def NAME#8i8 : BinOpAI_FF<BaseOpc4, mnemonic, Xi8 , AL,
1126 "{$src, %al|al, $src}">;
1127 def NAME#16i16 : BinOpAI_FF<BaseOpc4, mnemonic, Xi16, AX,
1128 "{$src, %ax|ax, $src}">;
1129 def NAME#32i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi32, EAX,
1130 "{$src, %eax|eax, $src}">;
1131 def NAME#64i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi64, RAX,
1132 "{$src, %rax|rax, $src}">;
1135 /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1136 /// defined with "(set EFLAGS, (...". It would be really nice to find a way
1137 /// to factor this with the other ArithBinOp_*.
1139 multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1140 string mnemonic, Format RegMRM, Format MemMRM,
1142 bit CommutableRR, bit ConvertibleToThreeAddress> {
1143 let Defs = [EFLAGS] in {
1144 let isCommutable = CommutableRR in {
1145 def NAME#8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1146 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1147 def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1148 def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1149 def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1153 def NAME#8rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
1154 def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
1155 def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
1156 def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
1158 def NAME#8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1159 def NAME#16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1160 def NAME#32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1161 def NAME#64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1163 def NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1165 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1166 // NOTE: These are order specific, we want the ri8 forms to be listed
1167 // first so that they are slightly preferred to the ri forms.
1168 def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1169 def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1170 def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1172 def NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1173 def NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1174 def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1177 def NAME#8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1178 def NAME#16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1179 def NAME#32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1180 def NAME#64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1182 // NOTE: These are order specific, we want the mi8 forms to be listed
1183 // first so that they are slightly preferred to the mi forms.
1184 def NAME#16mi8 : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1185 def NAME#32mi8 : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1186 def NAME#64mi8 : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1188 def NAME#8mi : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1189 def NAME#16mi : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1190 def NAME#32mi : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1191 def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1193 // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1194 // not in 64-bit mode.
1195 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1196 hasSideEffects = 0 in {
1197 def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1199 def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>;
1201 } // Defs = [EFLAGS]
1203 def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1204 "{$src, %al|al, $src}">;
1205 def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1206 "{$src, %ax|ax, $src}">;
1207 def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1208 "{$src, %eax|eax, $src}">;
1209 def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1210 "{$src, %rax|rax, $src}">;
1214 defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1215 X86and_flag, and, 1, 0>;
1216 defm OR : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1217 X86or_flag, or, 1, 0>;
1218 defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1219 X86xor_flag, xor, 1, 0>;
1220 defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1221 X86add_flag, add, 1, 1>;
1222 let isCompare = 1 in {
1223 defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1224 X86sub_flag, sub, 0, 0>;
1228 defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1230 defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1233 let isCompare = 1 in {
1234 defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1238 //===----------------------------------------------------------------------===//
1239 // Semantically, test instructions are similar like AND, except they don't
1240 // generate a result. From an encoding perspective, they are very different:
1241 // they don't have all the usual imm8 and REV forms, and are encoded into a
1243 def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1244 (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1246 let isCompare = 1 in {
1247 let Defs = [EFLAGS] in {
1248 let isCommutable = 1 in {
1249 def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>;
1250 def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>;
1251 def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>;
1252 def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>;
1255 def TEST8rm : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
1256 def TEST16rm : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
1257 def TEST32rm : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
1258 def TEST64rm : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
1260 def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1261 def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1262 def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1263 def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1265 def TEST8mi : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1266 def TEST16mi : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1267 def TEST32mi : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1268 def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1270 // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1271 // register class is constrained to GR8_NOREX. This pseudo is explicitly
1272 // marked side-effect free, since it doesn't have an isel pattern like
1273 // other test instructions.
1274 let isPseudo = 1, hasSideEffects = 0 in
1275 def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1276 "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1277 } // Defs = [EFLAGS]
1279 def TEST8i8 : BinOpAI<0xA8, "test", Xi8 , AL,
1280 "{$src, %al|al, $src}">;
1281 def TEST16i16 : BinOpAI<0xA8, "test", Xi16, AX,
1282 "{$src, %ax|ax, $src}">;
1283 def TEST32i32 : BinOpAI<0xA8, "test", Xi32, EAX,
1284 "{$src, %eax|eax, $src}">;
1285 def TEST64i32 : BinOpAI<0xA8, "test", Xi64, RAX,
1286 "{$src, %rax|rax, $src}">;
1289 //===----------------------------------------------------------------------===//
1292 multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1294 def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1295 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1296 [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1297 IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1298 def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1299 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1300 [(set RC:$dst, EFLAGS,
1301 (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1302 Sched<[WriteALULd, ReadAfterLd]>;
1305 let Predicates = [HasBMI], Defs = [EFLAGS] in {
1306 defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1307 defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1310 let Predicates = [HasBMI] in {
1311 def : Pat<(and (not GR32:$src1), GR32:$src2),
1312 (ANDN32rr GR32:$src1, GR32:$src2)>;
1313 def : Pat<(and (not GR64:$src1), GR64:$src2),
1314 (ANDN64rr GR64:$src1, GR64:$src2)>;
1315 def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1316 (ANDN32rm GR32:$src1, addr:$src2)>;
1317 def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1318 (ANDN64rm GR64:$src1, addr:$src2)>;
1321 //===----------------------------------------------------------------------===//
1324 multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1325 let hasSideEffects = 0 in {
1326 let isCommutable = 1 in
1327 def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1328 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1329 [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1332 def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1333 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1334 [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1338 let Predicates = [HasBMI2] in {
1340 defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1342 defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1345 //===----------------------------------------------------------------------===//
1348 let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1349 Constraints = "$src0 = $dst", AddedComplexity = 10 in {
1350 let SchedRW = [WriteALU] in {
1351 def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1352 (ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1353 [(set GR32:$dst, EFLAGS,
1354 (X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
1355 IIC_BIN_CARRY_NONMEM>, T8PD;
1356 def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1357 (ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1358 [(set GR64:$dst, EFLAGS,
1359 (X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
1360 IIC_BIN_CARRY_NONMEM>, T8PD;
1363 let mayLoad = 1, SchedRW = [WriteALULd] in {
1364 def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1365 (ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1366 [(set GR32:$dst, EFLAGS,
1367 (X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
1368 IIC_BIN_CARRY_MEM>, T8PD;
1370 def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1371 (ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1372 [(set GR64:$dst, EFLAGS,
1373 (X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
1374 IIC_BIN_CARRY_MEM>, T8PD;
1378 //===----------------------------------------------------------------------===//
1381 let Predicates = [HasADX], hasSideEffects = 0, Defs = [EFLAGS],
1382 Uses = [EFLAGS] in {
1383 let SchedRW = [WriteALU] in {
1384 def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1385 "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1387 def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1388 "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1391 let mayLoad = 1, SchedRW = [WriteALULd] in {
1392 def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1393 "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1395 def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1396 "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;