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