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