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