1//===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the integer arithmetic instructions in the X86 11// architecture. 12// 13//===----------------------------------------------------------------------===// 14 15//===----------------------------------------------------------------------===// 16// LEA - Load Effective Address 17let SchedRW = [WriteLEA] in { 18let hasSideEffects = 0 in 19def LEA16r : I<0x8D, MRMSrcMem, 20 (outs GR16:$dst), (ins anymem:$src), 21 "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize16; 22let isReMaterializable = 1 in 23def 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)]>, 27 OpSize32, Requires<[Not64BitMode]>; 28 29def 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)]>, 33 OpSize32, Requires<[In64BitMode]>; 34 35let isReMaterializable = 1 in 36def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src), 37 "lea{q}\t{$src|$dst}, {$dst|$src}", 38 [(set GR64:$dst, lea64addr:$src)]>; 39} // SchedRW 40 41//===----------------------------------------------------------------------===// 42// Fixed-Register Multiplication and Division Instructions. 43// 44 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 48// uses. 49class SchedLoadReg<SchedWrite SW> : Sched<[SW, 50 // Memory operand. 51 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, 52 // Register reads (implicit or explicit). 53 ReadAfterLd, ReadAfterLd]>; 54 55// Extra precision multiplication 56 57// AL is really implied by AX, but the registers in Defs must match the 58// SDNode results (i8, i32). 59// AL,AH = AL*GR8 60let Defs = [AL,EFLAGS,AX], Uses = [AL] in 61def 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)]>, Sched<[WriteIMul]>; 67// AX,DX = AX*GR16 68let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in 69def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src), 70 "mul{w}\t$src", 71 []>, OpSize16, Sched<[WriteIMul]>; 72// EAX,EDX = EAX*GR32 73let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in 74def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src), 75 "mul{l}\t$src", 76 [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/]>, 77 OpSize32, Sched<[WriteIMul]>; 78// RAX,RDX = RAX*GR64 79let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in 80def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src), 81 "mul{q}\t$src", 82 [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/]>, 83 Sched<[WriteIMul64]>; 84// AL,AH = AL*[mem8] 85let Defs = [AL,EFLAGS,AX], Uses = [AL] in 86def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src), 87 "mul{b}\t$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)]>, SchedLoadReg<WriteIMul.Folded>; 93// AX,DX = AX*[mem16] 94let mayLoad = 1, hasSideEffects = 0 in { 95let Defs = [AX,DX,EFLAGS], Uses = [AX] in 96def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src), 97 "mul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul.Folded>; 98// EAX,EDX = EAX*[mem32] 99let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in 100def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src), 101 "mul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul.Folded>; 102// RAX,RDX = RAX*[mem64] 103let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in 104def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src), 105 "mul{q}\t$src", []>, SchedLoadReg<WriteIMul64.Folded>, 106 Requires<[In64BitMode]>; 107} 108 109let hasSideEffects = 0 in { 110// AL,AH = AL*GR8 111let Defs = [AL,EFLAGS,AX], Uses = [AL] in 112def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>, 113 Sched<[WriteIMul]>; 114// AX,DX = AX*GR16 115let Defs = [AX,DX,EFLAGS], Uses = [AX] in 116def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", []>, 117 OpSize16, Sched<[WriteIMul]>; 118// EAX,EDX = EAX*GR32 119let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in 120def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>, 121 OpSize32, Sched<[WriteIMul]>; 122// RAX,RDX = RAX*GR64 123let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in 124def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", []>, 125 Sched<[WriteIMul64]>; 126 127let mayLoad = 1 in { 128// AL,AH = AL*[mem8] 129let Defs = [AL,EFLAGS,AX], Uses = [AL] in 130def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src), 131 "imul{b}\t$src", []>, SchedLoadReg<WriteIMul.Folded>; 132// AX,DX = AX*[mem16] 133let Defs = [AX,DX,EFLAGS], Uses = [AX] in 134def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src), 135 "imul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul.Folded>; 136// EAX,EDX = EAX*[mem32] 137let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in 138def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src), 139 "imul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul.Folded>; 140// RAX,RDX = RAX*[mem64] 141let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in 142def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src), 143 "imul{q}\t$src", []>, SchedLoadReg<WriteIMul64.Folded>, 144 Requires<[In64BitMode]>; 145} 146} // hasSideEffects 147 148 149let Defs = [EFLAGS] in { 150let Constraints = "$src1 = $dst" in { 151 152let isCommutable = 1 in { 153// X = IMUL Y, Z --> X = IMUL Z, Y 154// Register-Register Signed Integer Multiply 155def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2), 156 "imul{w}\t{$src2, $dst|$dst, $src2}", 157 [(set GR16:$dst, EFLAGS, 158 (X86smul_flag GR16:$src1, GR16:$src2))]>, 159 Sched<[WriteIMul]>, TB, OpSize16; 160def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2), 161 "imul{l}\t{$src2, $dst|$dst, $src2}", 162 [(set GR32:$dst, EFLAGS, 163 (X86smul_flag GR32:$src1, GR32:$src2))]>, 164 Sched<[WriteIMul]>, TB, OpSize32; 165def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst), 166 (ins GR64:$src1, GR64:$src2), 167 "imul{q}\t{$src2, $dst|$dst, $src2}", 168 [(set GR64:$dst, EFLAGS, 169 (X86smul_flag GR64:$src1, GR64:$src2))]>, 170 Sched<[WriteIMul64]>, TB; 171} // isCommutable 172 173// Register-Memory Signed Integer Multiply 174def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst), 175 (ins GR16:$src1, i16mem:$src2), 176 "imul{w}\t{$src2, $dst|$dst, $src2}", 177 [(set GR16:$dst, EFLAGS, 178 (X86smul_flag GR16:$src1, (loadi16 addr:$src2)))]>, 179 Sched<[WriteIMul.Folded, ReadAfterLd]>, TB, OpSize16; 180def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst), 181 (ins GR32:$src1, i32mem:$src2), 182 "imul{l}\t{$src2, $dst|$dst, $src2}", 183 [(set GR32:$dst, EFLAGS, 184 (X86smul_flag GR32:$src1, (loadi32 addr:$src2)))]>, 185 Sched<[WriteIMul.Folded, ReadAfterLd]>, TB, OpSize32; 186def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst), 187 (ins GR64:$src1, i64mem:$src2), 188 "imul{q}\t{$src2, $dst|$dst, $src2}", 189 [(set GR64:$dst, EFLAGS, 190 (X86smul_flag GR64:$src1, (loadi64 addr:$src2)))]>, 191 Sched<[WriteIMul64.Folded, ReadAfterLd]>, TB; 192} // Constraints = "$src1 = $dst" 193 194} // Defs = [EFLAGS] 195 196// Surprisingly enough, these are not two address instructions! 197let Defs = [EFLAGS] in { 198// Register-Integer Signed Integer Multiply 199def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16 200 (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 201 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 202 [(set GR16:$dst, EFLAGS, 203 (X86smul_flag GR16:$src1, imm:$src2))]>, 204 Sched<[WriteIMul]>, OpSize16; 205def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // GR16 = GR16*I8 206 (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), 207 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 208 [(set GR16:$dst, EFLAGS, 209 (X86smul_flag GR16:$src1, i16immSExt8:$src2))]>, 210 Sched<[WriteIMul]>, OpSize16; 211def IMUL32rri : Ii32<0x69, MRMSrcReg, // GR32 = GR32*I32 212 (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 213 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 214 [(set GR32:$dst, EFLAGS, 215 (X86smul_flag GR32:$src1, imm:$src2))]>, 216 Sched<[WriteIMul]>, OpSize32; 217def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8 218 (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), 219 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 220 [(set GR32:$dst, EFLAGS, 221 (X86smul_flag GR32:$src1, i32immSExt8:$src2))]>, 222 Sched<[WriteIMul]>, OpSize32; 223def IMUL64rri32 : RIi32S<0x69, MRMSrcReg, // GR64 = GR64*I32 224 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), 225 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 226 [(set GR64:$dst, EFLAGS, 227 (X86smul_flag GR64:$src1, i64immSExt32:$src2))]>, 228 Sched<[WriteIMul64]>; 229def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8 230 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), 231 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 232 [(set GR64:$dst, EFLAGS, 233 (X86smul_flag GR64:$src1, i64immSExt8:$src2))]>, 234 Sched<[WriteIMul64]>; 235 236// Memory-Integer Signed Integer Multiply 237def IMUL16rmi : Ii16<0x69, MRMSrcMem, // GR16 = [mem16]*I16 238 (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2), 239 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 240 [(set GR16:$dst, EFLAGS, 241 (X86smul_flag (loadi16 addr:$src1), imm:$src2))]>, 242 Sched<[WriteIMul.Folded]>, OpSize16; 243def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // GR16 = [mem16]*I8 244 (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2), 245 "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 246 [(set GR16:$dst, EFLAGS, 247 (X86smul_flag (loadi16 addr:$src1), 248 i16immSExt8:$src2))]>, 249 Sched<[WriteIMul.Folded]>, OpSize16; 250def IMUL32rmi : Ii32<0x69, MRMSrcMem, // GR32 = [mem32]*I32 251 (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2), 252 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 253 [(set GR32:$dst, EFLAGS, 254 (X86smul_flag (loadi32 addr:$src1), imm:$src2))]>, 255 Sched<[WriteIMul.Folded]>, OpSize32; 256def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8 257 (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2), 258 "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 259 [(set GR32:$dst, EFLAGS, 260 (X86smul_flag (loadi32 addr:$src1), 261 i32immSExt8:$src2))]>, 262 Sched<[WriteIMul.Folded]>, OpSize32; 263def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem, // GR64 = [mem64]*I32 264 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2), 265 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 266 [(set GR64:$dst, EFLAGS, 267 (X86smul_flag (loadi64 addr:$src1), 268 i64immSExt32:$src2))]>, 269 Sched<[WriteIMul64.Folded]>; 270def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8 271 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2), 272 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", 273 [(set GR64:$dst, EFLAGS, 274 (X86smul_flag (loadi64 addr:$src1), 275 i64immSExt8:$src2))]>, 276 Sched<[WriteIMul64.Folded]>; 277} // Defs = [EFLAGS] 278 279// unsigned division/remainder 280let hasSideEffects = 1 in { // so that we don't speculatively execute 281let Defs = [AL,AH,EFLAGS], Uses = [AX] in 282def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH 283 "div{b}\t$src", []>, Sched<[WriteDiv8]>; 284let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in 285def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX 286 "div{w}\t$src", []>, Sched<[WriteDiv16]>, OpSize16; 287let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in 288def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX 289 "div{l}\t$src", []>, Sched<[WriteDiv32]>, OpSize32; 290// RDX:RAX/r64 = RAX,RDX 291let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in 292def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), 293 "div{q}\t$src", []>, Sched<[WriteDiv64]>; 294 295let mayLoad = 1 in { 296let Defs = [AL,AH,EFLAGS], Uses = [AX] in 297def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH 298 "div{b}\t$src", []>, SchedLoadReg<WriteDiv8.Folded>; 299let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in 300def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX 301 "div{w}\t$src", []>, OpSize16, SchedLoadReg<WriteDiv16.Folded>; 302let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX 303def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src), 304 "div{l}\t$src", []>, SchedLoadReg<WriteDiv32.Folded>, OpSize32; 305// RDX:RAX/[mem64] = RAX,RDX 306let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in 307def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), 308 "div{q}\t$src", []>, SchedLoadReg<WriteDiv64.Folded>, 309 Requires<[In64BitMode]>; 310} 311 312// Signed division/remainder. 313let Defs = [AL,AH,EFLAGS], Uses = [AX] in 314def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH 315 "idiv{b}\t$src", []>, Sched<[WriteIDiv8]>; 316let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in 317def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX 318 "idiv{w}\t$src", []>, Sched<[WriteIDiv16]>, OpSize16; 319let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in 320def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX 321 "idiv{l}\t$src", []>, Sched<[WriteIDiv32]>, OpSize32; 322// RDX:RAX/r64 = RAX,RDX 323let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in 324def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), 325 "idiv{q}\t$src", []>, Sched<[WriteIDiv64]>; 326 327let mayLoad = 1 in { 328let Defs = [AL,AH,EFLAGS], Uses = [AX] in 329def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH 330 "idiv{b}\t$src", []>, SchedLoadReg<WriteIDiv8.Folded>; 331let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in 332def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX 333 "idiv{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIDiv16.Folded>; 334let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX 335def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), 336 "idiv{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIDiv32.Folded>; 337let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX 338def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), 339 "idiv{q}\t$src", []>, SchedLoadReg<WriteIDiv64.Folded>, 340 Requires<[In64BitMode]>; 341} 342} // hasSideEffects = 0 343 344//===----------------------------------------------------------------------===// 345// Two address Instructions. 346// 347 348// unary instructions 349let CodeSize = 2 in { 350let Defs = [EFLAGS] in { 351let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in { 352def NEG8r : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1), 353 "neg{b}\t$dst", 354 [(set GR8:$dst, (ineg GR8:$src1)), 355 (implicit EFLAGS)]>; 356def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1), 357 "neg{w}\t$dst", 358 [(set GR16:$dst, (ineg GR16:$src1)), 359 (implicit EFLAGS)]>, OpSize16; 360def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1), 361 "neg{l}\t$dst", 362 [(set GR32:$dst, (ineg GR32:$src1)), 363 (implicit EFLAGS)]>, OpSize32; 364def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst", 365 [(set GR64:$dst, (ineg GR64:$src1)), 366 (implicit EFLAGS)]>; 367} // Constraints = "$src1 = $dst", SchedRW 368 369// Read-modify-write negate. 370let SchedRW = [WriteALURMW] in { 371def NEG8m : I<0xF6, MRM3m, (outs), (ins i8mem :$dst), 372 "neg{b}\t$dst", 373 [(store (ineg (loadi8 addr:$dst)), addr:$dst), 374 (implicit EFLAGS)]>; 375def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst), 376 "neg{w}\t$dst", 377 [(store (ineg (loadi16 addr:$dst)), addr:$dst), 378 (implicit EFLAGS)]>, OpSize16; 379def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst), 380 "neg{l}\t$dst", 381 [(store (ineg (loadi32 addr:$dst)), addr:$dst), 382 (implicit EFLAGS)]>, OpSize32; 383def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst", 384 [(store (ineg (loadi64 addr:$dst)), addr:$dst), 385 (implicit EFLAGS)]>, 386 Requires<[In64BitMode]>; 387} // SchedRW 388} // Defs = [EFLAGS] 389 390 391// Note: NOT does not set EFLAGS! 392 393let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in { 394def NOT8r : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1), 395 "not{b}\t$dst", 396 [(set GR8:$dst, (not GR8:$src1))]>; 397def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1), 398 "not{w}\t$dst", 399 [(set GR16:$dst, (not GR16:$src1))]>, OpSize16; 400def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1), 401 "not{l}\t$dst", 402 [(set GR32:$dst, (not GR32:$src1))]>, OpSize32; 403def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst", 404 [(set GR64:$dst, (not GR64:$src1))]>; 405} // Constraints = "$src1 = $dst", SchedRW 406 407let SchedRW = [WriteALURMW] in { 408def NOT8m : I<0xF6, MRM2m, (outs), (ins i8mem :$dst), 409 "not{b}\t$dst", 410 [(store (not (loadi8 addr:$dst)), addr:$dst)]>; 411def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst), 412 "not{w}\t$dst", 413 [(store (not (loadi16 addr:$dst)), addr:$dst)]>, 414 OpSize16; 415def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst), 416 "not{l}\t$dst", 417 [(store (not (loadi32 addr:$dst)), addr:$dst)]>, 418 OpSize32; 419def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst", 420 [(store (not (loadi64 addr:$dst)), addr:$dst)]>, 421 Requires<[In64BitMode]>; 422} // SchedRW 423} // CodeSize 424 425// TODO: inc/dec is slow for P4, but fast for Pentium-M. 426let Defs = [EFLAGS] in { 427let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in { 428let CodeSize = 2 in 429def INC8r : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1), 430 "inc{b}\t$dst", 431 [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))]>; 432let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA. 433def INC16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1), 434 "inc{w}\t$dst", 435 [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))]>, OpSize16; 436def INC32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1), 437 "inc{l}\t$dst", 438 [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))]>, OpSize32; 439def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst", 440 [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))]>; 441} // isConvertibleToThreeAddress = 1, CodeSize = 2 442 443// Short forms only valid in 32-bit mode. Selected during MCInst lowering. 444let CodeSize = 1, hasSideEffects = 0 in { 445def INC16r_alt : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1), 446 "inc{w}\t$dst", []>, 447 OpSize16, Requires<[Not64BitMode]>; 448def INC32r_alt : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1), 449 "inc{l}\t$dst", []>, 450 OpSize32, Requires<[Not64BitMode]>; 451} // CodeSize = 1, hasSideEffects = 0 452} // Constraints = "$src1 = $dst", SchedRW 453 454let CodeSize = 2, SchedRW = [WriteALURMW] in { 455let Predicates = [UseIncDec] in { 456 def INC8m : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst", 457 [(store (add (loadi8 addr:$dst), 1), addr:$dst), 458 (implicit EFLAGS)]>; 459 def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst", 460 [(store (add (loadi16 addr:$dst), 1), addr:$dst), 461 (implicit EFLAGS)]>, OpSize16; 462 def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst", 463 [(store (add (loadi32 addr:$dst), 1), addr:$dst), 464 (implicit EFLAGS)]>, OpSize32; 465} // Predicates 466let Predicates = [UseIncDec, In64BitMode] in { 467 def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst", 468 [(store (add (loadi64 addr:$dst), 1), addr:$dst), 469 (implicit EFLAGS)]>; 470} // Predicates 471} // CodeSize = 2, SchedRW 472 473let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in { 474let CodeSize = 2 in 475def DEC8r : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1), 476 "dec{b}\t$dst", 477 [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))]>; 478let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA. 479def DEC16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1), 480 "dec{w}\t$dst", 481 [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))]>, OpSize16; 482def DEC32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1), 483 "dec{l}\t$dst", 484 [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))]>, OpSize32; 485def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst", 486 [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))]>; 487} // isConvertibleToThreeAddress = 1, CodeSize = 2 488 489// Short forms only valid in 32-bit mode. Selected during MCInst lowering. 490let CodeSize = 1, hasSideEffects = 0 in { 491def DEC16r_alt : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1), 492 "dec{w}\t$dst", []>, 493 OpSize16, Requires<[Not64BitMode]>; 494def DEC32r_alt : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1), 495 "dec{l}\t$dst", []>, 496 OpSize32, Requires<[Not64BitMode]>; 497} // CodeSize = 1, hasSideEffects = 0 498} // Constraints = "$src1 = $dst", SchedRW 499 500 501let CodeSize = 2, SchedRW = [WriteALURMW] in { 502let Predicates = [UseIncDec] in { 503 def DEC8m : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst", 504 [(store (add (loadi8 addr:$dst), -1), addr:$dst), 505 (implicit EFLAGS)]>; 506 def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst", 507 [(store (add (loadi16 addr:$dst), -1), addr:$dst), 508 (implicit EFLAGS)]>, OpSize16; 509 def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst", 510 [(store (add (loadi32 addr:$dst), -1), addr:$dst), 511 (implicit EFLAGS)]>, OpSize32; 512} // Predicates 513let Predicates = [UseIncDec, In64BitMode] in { 514 def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst", 515 [(store (add (loadi64 addr:$dst), -1), addr:$dst), 516 (implicit EFLAGS)]>; 517} // Predicates 518} // CodeSize = 2, SchedRW 519} // Defs = [EFLAGS] 520 521/// X86TypeInfo - This is a bunch of information that describes relevant X86 522/// information about value types. For example, it can tell you what the 523/// register class and preferred load to use. 524class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass, 525 PatFrag loadnode, X86MemOperand memoperand, ImmType immkind, 526 Operand immoperand, SDPatternOperator immoperator, 527 Operand imm8operand, SDPatternOperator imm8operator, 528 bit hasOddOpcode, OperandSize opSize, 529 bit hasREX_WPrefix> { 530 /// VT - This is the value type itself. 531 ValueType VT = vt; 532 533 /// InstrSuffix - This is the suffix used on instructions with this type. For 534 /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q". 535 string InstrSuffix = instrsuffix; 536 537 /// RegClass - This is the register class associated with this type. For 538 /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64. 539 RegisterClass RegClass = regclass; 540 541 /// LoadNode - This is the load node associated with this type. For 542 /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64. 543 PatFrag LoadNode = loadnode; 544 545 /// MemOperand - This is the memory operand associated with this type. For 546 /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem. 547 X86MemOperand MemOperand = memoperand; 548 549 /// ImmEncoding - This is the encoding of an immediate of this type. For 550 /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32. Note that i64 -> Imm32 551 /// since the immediate fields of i64 instructions is a 32-bit sign extended 552 /// value. 553 ImmType ImmEncoding = immkind; 554 555 /// ImmOperand - This is the operand kind of an immediate of this type. For 556 /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm. Note that i64 -> 557 /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign 558 /// extended value. 559 Operand ImmOperand = immoperand; 560 561 /// ImmOperator - This is the operator that should be used to match an 562 /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32). 563 SDPatternOperator ImmOperator = immoperator; 564 565 /// Imm8Operand - This is the operand kind to use for an imm8 of this type. 566 /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm. This is 567 /// only used for instructions that have a sign-extended imm8 field form. 568 Operand Imm8Operand = imm8operand; 569 570 /// Imm8Operator - This is the operator that should be used to match an 8-bit 571 /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8). 572 SDPatternOperator Imm8Operator = imm8operator; 573 574 /// HasOddOpcode - This bit is true if the instruction should have an odd (as 575 /// opposed to even) opcode. Operations on i8 are usually even, operations on 576 /// other datatypes are odd. 577 bit HasOddOpcode = hasOddOpcode; 578 579 /// OpSize - Selects whether the instruction needs a 0x66 prefix based on 580 /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this 581 /// to Opsize16. i32 sets this to OpSize32. 582 OperandSize OpSize = opSize; 583 584 /// HasREX_WPrefix - This bit is set to true if the instruction should have 585 /// the 0x40 REX prefix. This is set for i64 types. 586 bit HasREX_WPrefix = hasREX_WPrefix; 587} 588 589def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">; 590 591 592def Xi8 : X86TypeInfo<i8, "b", GR8, loadi8, i8mem, 593 Imm8, i8imm, imm8_su, i8imm, invalid_node, 594 0, OpSizeFixed, 0>; 595def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem, 596 Imm16, i16imm, imm16_su, i16i8imm, i16immSExt8_su, 597 1, OpSize16, 0>; 598def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem, 599 Imm32, i32imm, imm32_su, i32i8imm, i32immSExt8_su, 600 1, OpSize32, 0>; 601def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem, 602 Imm32S, i64i32imm, i64immSExt32_su, i64i8imm, i64immSExt8_su, 603 1, OpSizeFixed, 1>; 604 605/// ITy - This instruction base class takes the type info for the instruction. 606/// Using this, it: 607/// 1. Concatenates together the instruction mnemonic with the appropriate 608/// suffix letter, a tab, and the arguments. 609/// 2. Infers whether the instruction should have a 0x66 prefix byte. 610/// 3. Infers whether the instruction should have a 0x40 REX_W prefix. 611/// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations) 612/// or 1 (for i16,i32,i64 operations). 613class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins, 614 string mnemonic, string args, list<dag> pattern> 615 : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4}, 616 opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode }, 617 f, outs, ins, 618 !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern> { 619 620 // Infer instruction prefixes from type info. 621 let OpSize = typeinfo.OpSize; 622 let hasREX_WPrefix = typeinfo.HasREX_WPrefix; 623} 624 625// BinOpRR - Instructions like "add reg, reg, reg". 626class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 627 dag outlist, X86FoldableSchedWrite sched, list<dag> pattern> 628 : ITy<opcode, MRMDestReg, typeinfo, outlist, 629 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2), 630 mnemonic, "{$src2, $src1|$src1, $src2}", pattern>, 631 Sched<[sched]>; 632 633// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has 634// just a EFLAGS as a result. 635class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 636 SDPatternOperator opnode> 637 : BinOpRR<opcode, mnemonic, typeinfo, (outs), WriteALU, 638 [(set EFLAGS, 639 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>; 640 641// BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has 642// both a regclass and EFLAGS as a result. 643class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 644 SDNode opnode> 645 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU, 646 [(set typeinfo.RegClass:$dst, EFLAGS, 647 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>; 648 649// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has 650// both a regclass and EFLAGS as a result, and has EFLAGS as input. 651class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 652 SDNode opnode> 653 : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC, 654 [(set typeinfo.RegClass:$dst, EFLAGS, 655 (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2, 656 EFLAGS))]>; 657 658// BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding). 659class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 660 X86FoldableSchedWrite sched = WriteALU> 661 : ITy<opcode, MRMSrcReg, typeinfo, 662 (outs typeinfo.RegClass:$dst), 663 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2), 664 mnemonic, "{$src2, $dst|$dst, $src2}", []>, 665 Sched<[sched]> { 666 // The disassembler should know about this, but not the asmparser. 667 let isCodeGenOnly = 1; 668 let ForceDisassemble = 1; 669 let hasSideEffects = 0; 670} 671 672// BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding). 673class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo> 674 : BinOpRR_Rev<opcode, mnemonic, typeinfo, WriteADC>; 675 676// BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding). 677class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo> 678 : ITy<opcode, MRMSrcReg, typeinfo, (outs), 679 (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2), 680 mnemonic, "{$src2, $src1|$src1, $src2}", []>, 681 Sched<[WriteALU]> { 682 // The disassembler should know about this, but not the asmparser. 683 let isCodeGenOnly = 1; 684 let ForceDisassemble = 1; 685 let hasSideEffects = 0; 686} 687 688// BinOpRM - Instructions like "add reg, reg, [mem]". 689class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 690 dag outlist, X86FoldableSchedWrite sched, list<dag> pattern> 691 : ITy<opcode, MRMSrcMem, typeinfo, outlist, 692 (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2), 693 mnemonic, "{$src2, $src1|$src1, $src2}", pattern>, 694 Sched<[sched.Folded, ReadAfterLd]>; 695 696// BinOpRM_F - Instructions like "cmp reg, [mem]". 697class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 698 SDNode opnode> 699 : BinOpRM<opcode, mnemonic, typeinfo, (outs), WriteALU, 700 [(set EFLAGS, 701 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; 702 703// BinOpRM_RF - Instructions like "add reg, reg, [mem]". 704class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 705 SDNode opnode> 706 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU, 707 [(set typeinfo.RegClass:$dst, EFLAGS, 708 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; 709 710// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]". 711class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 712 SDNode opnode> 713 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC, 714 [(set typeinfo.RegClass:$dst, EFLAGS, 715 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2), 716 EFLAGS))]>; 717 718// BinOpRI - Instructions like "add reg, reg, imm". 719class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 720 Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern> 721 : ITy<opcode, f, typeinfo, outlist, 722 (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2), 723 mnemonic, "{$src2, $src1|$src1, $src2}", pattern>, 724 Sched<[sched]> { 725 let ImmT = typeinfo.ImmEncoding; 726} 727 728// BinOpRI_F - Instructions like "cmp reg, imm". 729class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 730 SDPatternOperator opnode, Format f> 731 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs), WriteALU, 732 [(set EFLAGS, 733 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; 734 735// BinOpRI_RF - Instructions like "add reg, reg, imm". 736class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 737 SDNode opnode, Format f> 738 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU, 739 [(set typeinfo.RegClass:$dst, EFLAGS, 740 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; 741// BinOpRI_RFF - Instructions like "adc reg, reg, imm". 742class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 743 SDNode opnode, Format f> 744 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC, 745 [(set typeinfo.RegClass:$dst, EFLAGS, 746 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2, 747 EFLAGS))]>; 748 749// BinOpRI8 - Instructions like "add reg, reg, imm8". 750class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 751 Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern> 752 : ITy<opcode, f, typeinfo, outlist, 753 (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2), 754 mnemonic, "{$src2, $src1|$src1, $src2}", pattern>, 755 Sched<[sched]> { 756 let ImmT = Imm8; // Always 8-bit immediate. 757} 758 759// BinOpRI8_F - Instructions like "cmp reg, imm8". 760class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 761 SDPatternOperator opnode, Format f> 762 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs), WriteALU, 763 [(set EFLAGS, 764 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; 765 766// BinOpRI8_RF - Instructions like "add reg, reg, imm8". 767class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 768 SDPatternOperator opnode, Format f> 769 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU, 770 [(set typeinfo.RegClass:$dst, EFLAGS, 771 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; 772 773// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8". 774class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 775 SDPatternOperator opnode, Format f> 776 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC, 777 [(set typeinfo.RegClass:$dst, EFLAGS, 778 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2, 779 EFLAGS))]>; 780 781// BinOpMR - Instructions like "add [mem], reg". 782class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 783 list<dag> pattern> 784 : ITy<opcode, MRMDestMem, typeinfo, 785 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src), 786 mnemonic, "{$src, $dst|$dst, $src}", pattern>; 787 788// BinOpMR_RMW - Instructions like "add [mem], reg". 789class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 790 SDNode opnode> 791 : BinOpMR<opcode, mnemonic, typeinfo, 792 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst), 793 (implicit EFLAGS)]>, Sched<[WriteALURMW]>; 794 795// BinOpMR_RMW_FF - Instructions like "adc [mem], reg". 796class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 797 SDNode opnode> 798 : BinOpMR<opcode, mnemonic, typeinfo, 799 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS), 800 addr:$dst), 801 (implicit EFLAGS)]>, Sched<[WriteADCRMW]>; 802 803// BinOpMR_F - Instructions like "cmp [mem], reg". 804class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 805 SDPatternOperator opnode> 806 : BinOpMR<opcode, mnemonic, typeinfo, 807 [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst), 808 typeinfo.RegClass:$src))]>, 809 Sched<[WriteALULd, ReadDefault, ReadDefault, ReadDefault, 810 ReadDefault, ReadDefault, ReadAfterLd]>; 811 812// BinOpMI - Instructions like "add [mem], imm". 813class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 814 Format f, list<dag> pattern> 815 : ITy<opcode, f, typeinfo, 816 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src), 817 mnemonic, "{$src, $dst|$dst, $src}", pattern> { 818 let ImmT = typeinfo.ImmEncoding; 819} 820 821// BinOpMI_RMW - Instructions like "add [mem], imm". 822class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 823 SDNode opnode, Format f> 824 : BinOpMI<opcode, mnemonic, typeinfo, f, 825 [(store (opnode (typeinfo.VT (load addr:$dst)), 826 typeinfo.ImmOperator:$src), addr:$dst), 827 (implicit EFLAGS)]>, Sched<[WriteALURMW]>; 828// BinOpMI_RMW_FF - Instructions like "adc [mem], imm". 829class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 830 SDNode opnode, Format f> 831 : BinOpMI<opcode, mnemonic, typeinfo, f, 832 [(store (opnode (typeinfo.VT (load addr:$dst)), 833 typeinfo.ImmOperator:$src, EFLAGS), addr:$dst), 834 (implicit EFLAGS)]>, Sched<[WriteADCRMW]>; 835 836// BinOpMI_F - Instructions like "cmp [mem], imm". 837class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 838 SDPatternOperator opnode, Format f> 839 : BinOpMI<opcode, mnemonic, typeinfo, f, 840 [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst), 841 typeinfo.ImmOperator:$src))]>, 842 Sched<[WriteALULd]>; 843 844// BinOpMI8 - Instructions like "add [mem], imm8". 845class BinOpMI8<string mnemonic, X86TypeInfo typeinfo, 846 Format f, list<dag> pattern> 847 : ITy<0x82, f, typeinfo, 848 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src), 849 mnemonic, "{$src, $dst|$dst, $src}", pattern> { 850 let ImmT = Imm8; // Always 8-bit immediate. 851} 852 853// BinOpMI8_RMW - Instructions like "add [mem], imm8". 854class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo, 855 SDPatternOperator opnode, Format f> 856 : BinOpMI8<mnemonic, typeinfo, f, 857 [(store (opnode (load addr:$dst), 858 typeinfo.Imm8Operator:$src), addr:$dst), 859 (implicit EFLAGS)]>, Sched<[WriteALURMW]>; 860 861// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8". 862class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo, 863 SDPatternOperator opnode, Format f> 864 : BinOpMI8<mnemonic, typeinfo, f, 865 [(store (opnode (load addr:$dst), 866 typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst), 867 (implicit EFLAGS)]>, Sched<[WriteADCRMW]>; 868 869// BinOpMI8_F - Instructions like "cmp [mem], imm8". 870class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo, 871 SDPatternOperator opnode, Format f> 872 : BinOpMI8<mnemonic, typeinfo, f, 873 [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst), 874 typeinfo.Imm8Operator:$src))]>, 875 Sched<[WriteALULd]>; 876 877// BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS. 878class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 879 Register areg, string operands, X86FoldableSchedWrite sched = WriteALU> 880 : ITy<opcode, RawFrm, typeinfo, 881 (outs), (ins typeinfo.ImmOperand:$src), 882 mnemonic, operands, []>, Sched<[sched]> { 883 let ImmT = typeinfo.ImmEncoding; 884 let Uses = [areg]; 885 let Defs = [areg, EFLAGS]; 886 let hasSideEffects = 0; 887} 888 889// BinOpAI_RFF - Instructions like "adc %eax, %eax, imm", that implicitly define 890// and use EFLAGS. 891class BinOpAI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 892 Register areg, string operands> 893 : BinOpAI<opcode, mnemonic, typeinfo, areg, operands, WriteADC> { 894 let Uses = [areg, EFLAGS]; 895} 896 897// BinOpAI_F - Instructions like "cmp %eax, %eax, imm", that imp-def EFLAGS. 898class BinOpAI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 899 Register areg, string operands> 900 : BinOpAI<opcode, mnemonic, typeinfo, areg, operands> { 901 let Defs = [EFLAGS]; 902} 903 904/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is 905/// defined with "(set GPR:$dst, EFLAGS, (...". 906/// 907/// It would be nice to get rid of the second and third argument here, but 908/// tblgen can't handle dependent type references aggressively enough: PR8330 909multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 910 string mnemonic, Format RegMRM, Format MemMRM, 911 SDNode opnodeflag, SDNode opnode, 912 bit CommutableRR, bit ConvertibleToThreeAddress> { 913 let Defs = [EFLAGS] in { 914 let Constraints = "$src1 = $dst" in { 915 let isCommutable = CommutableRR in { 916 def NAME#8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>; 917 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 918 def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>; 919 def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>; 920 def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>; 921 } // isConvertibleToThreeAddress 922 } // isCommutable 923 924 def NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>; 925 def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>; 926 def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>; 927 def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>; 928 929 def NAME#8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>; 930 def NAME#16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>; 931 def NAME#32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>; 932 def NAME#64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>; 933 934 def NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>; 935 936 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 937 // NOTE: These are order specific, we want the ri8 forms to be listed 938 // first so that they are slightly preferred to the ri forms. 939 def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>; 940 def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>; 941 def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>; 942 943 def NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>; 944 def NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>; 945 def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>; 946 } 947 } // Constraints = "$src1 = $dst" 948 949 let mayLoad = 1, mayStore = 1 in { 950 def NAME#8mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>; 951 def NAME#16mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>; 952 def NAME#32mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>; 953 def NAME#64mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>; 954 } 955 956 // NOTE: These are order specific, we want the mi8 forms to be listed 957 // first so that they are slightly preferred to the mi forms. 958 def NAME#16mi8 : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>; 959 def NAME#32mi8 : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>; 960 let Predicates = [In64BitMode] in 961 def NAME#64mi8 : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>; 962 963 def NAME#8mi : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>; 964 def NAME#16mi : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>; 965 def NAME#32mi : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>; 966 let Predicates = [In64BitMode] in 967 def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>; 968 969 // These are for the disassembler since 0x82 opcode behaves like 0x80, but 970 // not in 64-bit mode. 971 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1, 972 hasSideEffects = 0 in { 973 let Constraints = "$src1 = $dst" in 974 def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>; 975 let mayLoad = 1, mayStore = 1 in 976 def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>; 977 } 978 } // Defs = [EFLAGS] 979 980 def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL, 981 "{$src, %al|al, $src}">; 982 def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX, 983 "{$src, %ax|ax, $src}">; 984 def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX, 985 "{$src, %eax|eax, $src}">; 986 def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX, 987 "{$src, %rax|rax, $src}">; 988} 989 990/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is 991/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and 992/// SBB. 993/// 994/// It would be nice to get rid of the second and third argument here, but 995/// tblgen can't handle dependent type references aggressively enough: PR8330 996multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 997 string mnemonic, Format RegMRM, Format MemMRM, 998 SDNode opnode, bit CommutableRR, 999 bit ConvertibleToThreeAddress> { 1000 let Uses = [EFLAGS], Defs = [EFLAGS] in { 1001 let Constraints = "$src1 = $dst" in { 1002 let isCommutable = CommutableRR in { 1003 def NAME#8rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>; 1004 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1005 def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>; 1006 def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>; 1007 def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>; 1008 } // isConvertibleToThreeAddress 1009 } // isCommutable 1010 1011 def NAME#8rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>; 1012 def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>; 1013 def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>; 1014 def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>; 1015 1016 def NAME#8rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>; 1017 def NAME#16rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>; 1018 def NAME#32rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>; 1019 def NAME#64rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>; 1020 1021 def NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>; 1022 1023 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1024 // NOTE: These are order specific, we want the ri8 forms to be listed 1025 // first so that they are slightly preferred to the ri forms. 1026 def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>; 1027 def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>; 1028 def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>; 1029 1030 def NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>; 1031 def NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>; 1032 def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>; 1033 } 1034 } // Constraints = "$src1 = $dst" 1035 1036 def NAME#8mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>; 1037 def NAME#16mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>; 1038 def NAME#32mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>; 1039 def NAME#64mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>; 1040 1041 // NOTE: These are order specific, we want the mi8 forms to be listed 1042 // first so that they are slightly preferred to the mi forms. 1043 def NAME#16mi8 : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>; 1044 def NAME#32mi8 : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>; 1045 let Predicates = [In64BitMode] in 1046 def NAME#64mi8 : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>; 1047 1048 def NAME#8mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>; 1049 def NAME#16mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>; 1050 def NAME#32mi : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>; 1051 let Predicates = [In64BitMode] in 1052 def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>; 1053 1054 // These are for the disassembler since 0x82 opcode behaves like 0x80, but 1055 // not in 64-bit mode. 1056 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1, 1057 hasSideEffects = 0 in { 1058 let Constraints = "$src1 = $dst" in 1059 def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>; 1060 let mayLoad = 1, mayStore = 1 in 1061 def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>; 1062 } 1063 } // Uses = [EFLAGS], Defs = [EFLAGS] 1064 1065 def NAME#8i8 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi8 , AL, 1066 "{$src, %al|al, $src}">; 1067 def NAME#16i16 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi16, AX, 1068 "{$src, %ax|ax, $src}">; 1069 def NAME#32i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi32, EAX, 1070 "{$src, %eax|eax, $src}">; 1071 def NAME#64i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi64, RAX, 1072 "{$src, %rax|rax, $src}">; 1073} 1074 1075/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is 1076/// defined with "(set EFLAGS, (...". It would be really nice to find a way 1077/// to factor this with the other ArithBinOp_*. 1078/// 1079multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 1080 string mnemonic, Format RegMRM, Format MemMRM, 1081 SDNode opnode, 1082 bit CommutableRR, bit ConvertibleToThreeAddress> { 1083 let Defs = [EFLAGS] in { 1084 let isCommutable = CommutableRR in { 1085 def NAME#8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>; 1086 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1087 def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>; 1088 def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>; 1089 def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>; 1090 } 1091 } // isCommutable 1092 1093 def NAME#8rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>; 1094 def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>; 1095 def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>; 1096 def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>; 1097 1098 def NAME#8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>; 1099 def NAME#16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>; 1100 def NAME#32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>; 1101 def NAME#64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>; 1102 1103 def NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>; 1104 1105 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1106 // NOTE: These are order specific, we want the ri8 forms to be listed 1107 // first so that they are slightly preferred to the ri forms. 1108 def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>; 1109 def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>; 1110 def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>; 1111 1112 def NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>; 1113 def NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>; 1114 def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>; 1115 } 1116 1117 def NAME#8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>; 1118 def NAME#16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>; 1119 def NAME#32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>; 1120 def NAME#64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>; 1121 1122 // NOTE: These are order specific, we want the mi8 forms to be listed 1123 // first so that they are slightly preferred to the mi forms. 1124 def NAME#16mi8 : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>; 1125 def NAME#32mi8 : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>; 1126 let Predicates = [In64BitMode] in 1127 def NAME#64mi8 : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>; 1128 1129 def NAME#8mi : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>; 1130 def NAME#16mi : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>; 1131 def NAME#32mi : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>; 1132 let Predicates = [In64BitMode] in 1133 def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>; 1134 1135 // These are for the disassembler since 0x82 opcode behaves like 0x80, but 1136 // not in 64-bit mode. 1137 let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1, 1138 hasSideEffects = 0 in { 1139 def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>; 1140 let mayLoad = 1 in 1141 def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>; 1142 } 1143 } // Defs = [EFLAGS] 1144 1145 def NAME#8i8 : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL, 1146 "{$src, %al|al, $src}">; 1147 def NAME#16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX, 1148 "{$src, %ax|ax, $src}">; 1149 def NAME#32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX, 1150 "{$src, %eax|eax, $src}">; 1151 def NAME#64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX, 1152 "{$src, %rax|rax, $src}">; 1153} 1154 1155 1156defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m, 1157 X86and_flag, and, 1, 0>; 1158defm OR : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m, 1159 X86or_flag, or, 1, 0>; 1160defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m, 1161 X86xor_flag, xor, 1, 0>; 1162defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m, 1163 X86add_flag, add, 1, 1>; 1164let isCompare = 1 in { 1165defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m, 1166 X86sub_flag, sub, 0, 0>; 1167} 1168 1169// Arithmetic. 1170defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag, 1171 1, 0>; 1172defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag, 1173 0, 0>; 1174 1175let isCompare = 1 in { 1176defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; 1177} 1178 1179 1180//===----------------------------------------------------------------------===// 1181// Semantically, test instructions are similar like AND, except they don't 1182// generate a result. From an encoding perspective, they are very different: 1183// they don't have all the usual imm8 and REV forms, and are encoded into a 1184// different space. 1185def X86testpat : PatFrag<(ops node:$lhs, node:$rhs), 1186 (X86cmp (and_su node:$lhs, node:$rhs), 0)>; 1187 1188let isCompare = 1 in { 1189 let Defs = [EFLAGS] in { 1190 let isCommutable = 1 in { 1191 def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat>; 1192 def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat>; 1193 def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat>; 1194 def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat>; 1195 } // isCommutable 1196 1197 def TEST8mr : BinOpMR_F<0x84, "test", Xi8 , X86testpat>; 1198 def TEST16mr : BinOpMR_F<0x84, "test", Xi16, X86testpat>; 1199 def TEST32mr : BinOpMR_F<0x84, "test", Xi32, X86testpat>; 1200 def TEST64mr : BinOpMR_F<0x84, "test", Xi64, X86testpat>; 1201 1202 def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>; 1203 def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>; 1204 def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>; 1205 let Predicates = [In64BitMode] in 1206 def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>; 1207 1208 def TEST8mi : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>; 1209 def TEST16mi : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>; 1210 def TEST32mi : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>; 1211 let Predicates = [In64BitMode] in 1212 def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>; 1213 } // Defs = [EFLAGS] 1214 1215 def TEST8i8 : BinOpAI_F<0xA8, "test", Xi8 , AL, 1216 "{$src, %al|al, $src}">; 1217 def TEST16i16 : BinOpAI_F<0xA8, "test", Xi16, AX, 1218 "{$src, %ax|ax, $src}">; 1219 def TEST32i32 : BinOpAI_F<0xA8, "test", Xi32, EAX, 1220 "{$src, %eax|eax, $src}">; 1221 def TEST64i32 : BinOpAI_F<0xA8, "test", Xi64, RAX, 1222 "{$src, %rax|rax, $src}">; 1223} // isCompare 1224 1225//===----------------------------------------------------------------------===// 1226// ANDN Instruction 1227// 1228multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop, 1229 PatFrag ld_frag> { 1230 def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2), 1231 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 1232 [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))]>, 1233 Sched<[WriteALU]>; 1234 def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2), 1235 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 1236 [(set RC:$dst, EFLAGS, 1237 (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))]>, 1238 Sched<[WriteALULd, ReadAfterLd]>; 1239} 1240 1241// Complexity is reduced to give and with immediate a chance to match first. 1242let Predicates = [HasBMI], Defs = [EFLAGS], AddedComplexity = -6 in { 1243 defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V; 1244 defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W; 1245} 1246 1247let Predicates = [HasBMI], AddedComplexity = -6 in { 1248 def : Pat<(and (not GR32:$src1), GR32:$src2), 1249 (ANDN32rr GR32:$src1, GR32:$src2)>; 1250 def : Pat<(and (not GR64:$src1), GR64:$src2), 1251 (ANDN64rr GR64:$src1, GR64:$src2)>; 1252 def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)), 1253 (ANDN32rm GR32:$src1, addr:$src2)>; 1254 def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)), 1255 (ANDN64rm GR64:$src1, addr:$src2)>; 1256} 1257 1258//===----------------------------------------------------------------------===// 1259// MULX Instruction 1260// 1261multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop, 1262 X86FoldableSchedWrite sched> { 1263let hasSideEffects = 0 in { 1264 let isCommutable = 1 in 1265 def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src), 1266 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"), 1267 []>, T8XD, VEX_4V, Sched<[sched, WriteIMulH]>; 1268 1269 let mayLoad = 1 in 1270 def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src), 1271 !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"), 1272 []>, T8XD, VEX_4V, Sched<[sched.Folded, WriteIMulH]>; 1273} 1274} 1275 1276let Predicates = [HasBMI2] in { 1277 let Uses = [EDX] in 1278 defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem, WriteIMul>; 1279 let Uses = [RDX] in 1280 defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem, WriteIMul64>, VEX_W; 1281} 1282 1283//===----------------------------------------------------------------------===// 1284// ADCX and ADOX Instructions 1285// 1286let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS], 1287 Constraints = "$src1 = $dst", AddedComplexity = 10 in { 1288 let SchedRW = [WriteADC] in { 1289 def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), 1290 (ins GR32:$src1, GR32:$src2), 1291 "adcx{l}\t{$src2, $dst|$dst, $src2}", 1292 [(set GR32:$dst, EFLAGS, 1293 (X86adc_flag GR32:$src1, GR32:$src2, EFLAGS))]>, T8PD; 1294 def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), 1295 (ins GR64:$src1, GR64:$src2), 1296 "adcx{q}\t{$src2, $dst|$dst, $src2}", 1297 [(set GR64:$dst, EFLAGS, 1298 (X86adc_flag GR64:$src1, GR64:$src2, EFLAGS))]>, T8PD; 1299 1300 // We don't have patterns for ADOX yet. 1301 let hasSideEffects = 0 in { 1302 def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), 1303 (ins GR32:$src1, GR32:$src2), 1304 "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS; 1305 1306 def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), 1307 (ins GR64:$src1, GR64:$src2), 1308 "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS; 1309 } // hasSideEffects = 0 1310 } // SchedRW 1311 1312 let mayLoad = 1, SchedRW = [WriteADCLd, ReadAfterLd] in { 1313 def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), 1314 (ins GR32:$src1, i32mem:$src2), 1315 "adcx{l}\t{$src2, $dst|$dst, $src2}", 1316 [(set GR32:$dst, EFLAGS, 1317 (X86adc_flag GR32:$src1, (loadi32 addr:$src2), EFLAGS))]>, 1318 T8PD; 1319 1320 def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), 1321 (ins GR64:$src1, i64mem:$src2), 1322 "adcx{q}\t{$src2, $dst|$dst, $src2}", 1323 [(set GR64:$dst, EFLAGS, 1324 (X86adc_flag GR64:$src1, (loadi64 addr:$src2), EFLAGS))]>, 1325 T8PD; 1326 1327 // We don't have patterns for ADOX yet. 1328 let hasSideEffects = 0 in { 1329 def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), 1330 (ins GR32:$src1, i32mem:$src2), 1331 "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS; 1332 1333 def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), 1334 (ins GR64:$src1, i64mem:$src2), 1335 "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS; 1336 } // hasSideEffects = 0 1337 } // mayLoad = 1, SchedRW = [WriteADCLd] 1338} 1339