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 // BinOpRM - Instructions like "add reg, reg, [mem]". 654 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 655 dag outlist, list<dag> pattern> 656 : ITy<opcode, MRMSrcMem, typeinfo, outlist, 657 (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2), 658 mnemonic, "{$src2, $src1|$src1, $src2}", pattern>; 659 660 // BinOpRM_R - Instructions like "add reg, reg, [mem]". 661 class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 662 SDNode opnode> 663 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), 664 [(set typeinfo.RegClass:$dst, 665 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; 666 667 // BinOpRM_F - Instructions like "cmp reg, [mem]". 668 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 669 SDPatternOperator opnode> 670 : BinOpRM<opcode, mnemonic, typeinfo, (outs), 671 [(set EFLAGS, 672 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; 673 674 // BinOpRM_RF - Instructions like "add reg, reg, [mem]". 675 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 676 SDNode opnode> 677 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), 678 [(set typeinfo.RegClass:$dst, EFLAGS, 679 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; 680 681 // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]". 682 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 683 SDNode opnode> 684 : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), 685 [(set typeinfo.RegClass:$dst, EFLAGS, 686 (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2), 687 EFLAGS))]>; 688 689 // BinOpRI - Instructions like "add reg, reg, imm". 690 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 691 Format f, dag outlist, list<dag> pattern> 692 : ITy<opcode, f, typeinfo, outlist, 693 (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2), 694 mnemonic, "{$src2, $src1|$src1, $src2}", pattern> { 695 let ImmT = typeinfo.ImmEncoding; 696 } 697 698 // BinOpRI_R - Instructions like "add reg, reg, imm". 699 class BinOpRI_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 700 SDNode opnode, Format f> 701 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 702 [(set typeinfo.RegClass:$dst, 703 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; 704 705 // BinOpRI_F - Instructions like "cmp reg, imm". 706 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 707 SDPatternOperator opnode, Format f> 708 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs), 709 [(set EFLAGS, 710 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; 711 712 // BinOpRI_RF - Instructions like "add reg, reg, imm". 713 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 714 SDNode opnode, Format f> 715 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 716 [(set typeinfo.RegClass:$dst, EFLAGS, 717 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; 718 719 // BinOpRI_RFF - Instructions like "adc reg, reg, imm". 720 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 721 SDNode opnode, Format f> 722 : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 723 [(set typeinfo.RegClass:$dst, EFLAGS, 724 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2, 725 EFLAGS))]>; 726 727 // BinOpRI8 - Instructions like "add reg, reg, imm8". 728 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 729 Format f, dag outlist, list<dag> pattern> 730 : ITy<opcode, f, typeinfo, outlist, 731 (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2), 732 mnemonic, "{$src2, $src1|$src1, $src2}", pattern> { 733 let ImmT = Imm8; // Always 8-bit immediate. 734 } 735 736 // BinOpRI8_R - Instructions like "add reg, reg, imm8". 737 class BinOpRI8_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 738 SDNode opnode, Format f> 739 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 740 [(set typeinfo.RegClass:$dst, 741 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; 742 743 // BinOpRI8_F - Instructions like "cmp reg, imm8". 744 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 745 SDNode opnode, Format f> 746 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs), 747 [(set EFLAGS, 748 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; 749 750 // BinOpRI8_RF - Instructions like "add reg, reg, imm8". 751 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 752 SDNode opnode, Format f> 753 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 754 [(set typeinfo.RegClass:$dst, EFLAGS, 755 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; 756 757 // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8". 758 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 759 SDNode opnode, Format f> 760 : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), 761 [(set typeinfo.RegClass:$dst, EFLAGS, 762 (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2, 763 EFLAGS))]>; 764 765 // BinOpMR - Instructions like "add [mem], reg". 766 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 767 list<dag> pattern> 768 : ITy<opcode, MRMDestMem, typeinfo, 769 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src), 770 mnemonic, "{$src, $dst|$dst, $src}", pattern>; 771 772 // BinOpMR_RMW - Instructions like "add [mem], reg". 773 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 774 SDNode opnode> 775 : BinOpMR<opcode, mnemonic, typeinfo, 776 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst), 777 (implicit EFLAGS)]>; 778 779 // BinOpMR_RMW_FF - Instructions like "adc [mem], reg". 780 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 781 SDNode opnode> 782 : BinOpMR<opcode, mnemonic, typeinfo, 783 [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS), 784 addr:$dst), 785 (implicit EFLAGS)]>; 786 787 // BinOpMR_F - Instructions like "cmp [mem], reg". 788 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 789 SDNode opnode> 790 : BinOpMR<opcode, mnemonic, typeinfo, 791 [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>; 792 793 // BinOpMI - Instructions like "add [mem], imm". 794 class BinOpMI<string mnemonic, X86TypeInfo typeinfo, 795 Format f, list<dag> pattern, bits<8> opcode = 0x80> 796 : ITy<opcode, f, typeinfo, 797 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src), 798 mnemonic, "{$src, $dst|$dst, $src}", pattern> { 799 let ImmT = typeinfo.ImmEncoding; 800 } 801 802 // BinOpMI_RMW - Instructions like "add [mem], imm". 803 class BinOpMI_RMW<string mnemonic, X86TypeInfo typeinfo, 804 SDNode opnode, Format f> 805 : BinOpMI<mnemonic, typeinfo, f, 806 [(store (opnode (typeinfo.VT (load addr:$dst)), 807 typeinfo.ImmOperator:$src), addr:$dst), 808 (implicit EFLAGS)]>; 809 810 // BinOpMI_RMW_FF - Instructions like "adc [mem], imm". 811 class BinOpMI_RMW_FF<string mnemonic, X86TypeInfo typeinfo, 812 SDNode opnode, Format f> 813 : BinOpMI<mnemonic, typeinfo, f, 814 [(store (opnode (typeinfo.VT (load addr:$dst)), 815 typeinfo.ImmOperator:$src, EFLAGS), addr:$dst), 816 (implicit EFLAGS)]>; 817 818 // BinOpMI_F - Instructions like "cmp [mem], imm". 819 class BinOpMI_F<string mnemonic, X86TypeInfo typeinfo, 820 SDPatternOperator opnode, Format f, bits<8> opcode = 0x80> 821 : BinOpMI<mnemonic, typeinfo, f, 822 [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)), 823 typeinfo.ImmOperator:$src))], 824 opcode>; 825 826 // BinOpMI8 - Instructions like "add [mem], imm8". 827 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo, 828 Format f, list<dag> pattern> 829 : ITy<0x82, f, typeinfo, 830 (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src), 831 mnemonic, "{$src, $dst|$dst, $src}", pattern> { 832 let ImmT = Imm8; // Always 8-bit immediate. 833 } 834 835 // BinOpMI8_RMW - Instructions like "add [mem], imm8". 836 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo, 837 SDNode opnode, Format f> 838 : BinOpMI8<mnemonic, typeinfo, f, 839 [(store (opnode (load addr:$dst), 840 typeinfo.Imm8Operator:$src), addr:$dst), 841 (implicit EFLAGS)]>; 842 843 // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8". 844 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo, 845 SDNode opnode, Format f> 846 : BinOpMI8<mnemonic, typeinfo, f, 847 [(store (opnode (load addr:$dst), 848 typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst), 849 (implicit EFLAGS)]>; 850 851 // BinOpMI8_F - Instructions like "cmp [mem], imm8". 852 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo, 853 SDNode opnode, Format f> 854 : BinOpMI8<mnemonic, typeinfo, f, 855 [(set EFLAGS, (opnode (load addr:$dst), 856 typeinfo.Imm8Operator:$src))]>; 857 858 // BinOpAI - Instructions like "add %eax, %eax, imm". 859 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, 860 Register areg> 861 : ITy<opcode, RawFrm, typeinfo, 862 (outs), (ins typeinfo.ImmOperand:$src), 863 mnemonic, !strconcat("{$src, %", areg.AsmName, "|%", 864 areg.AsmName, ", $src}"), []> { 865 let ImmT = typeinfo.ImmEncoding; 866 let Uses = [areg]; 867 let Defs = [areg]; 868 } 869 870 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is 871 /// defined with "(set GPR:$dst, EFLAGS, (...". 872 /// 873 /// It would be nice to get rid of the second and third argument here, but 874 /// tblgen can't handle dependent type references aggressively enough: PR8330 875 multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 876 string mnemonic, Format RegMRM, Format MemMRM, 877 SDNode opnodeflag, SDNode opnode, 878 bit CommutableRR, bit ConvertibleToThreeAddress> { 879 let Defs = [EFLAGS] in { 880 let Constraints = "$src1 = $dst" in { 881 let isCommutable = CommutableRR, 882 isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 883 def #NAME#8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>; 884 def #NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>; 885 def #NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>; 886 def #NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>; 887 } // isCommutable 888 889 def #NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>; 890 def #NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>; 891 def #NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>; 892 def #NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>; 893 894 def #NAME#8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>; 895 def #NAME#16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>; 896 def #NAME#32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>; 897 def #NAME#64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>; 898 899 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 900 // NOTE: These are order specific, we want the ri8 forms to be listed 901 // first so that they are slightly preferred to the ri forms. 902 def #NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>; 903 def #NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>; 904 def #NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>; 905 906 def #NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>; 907 def #NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>; 908 def #NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>; 909 def #NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>; 910 } 911 } // Constraints = "$src1 = $dst" 912 913 def #NAME#8mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>; 914 def #NAME#16mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>; 915 def #NAME#32mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>; 916 def #NAME#64mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>; 917 918 // NOTE: These are order specific, we want the mi8 forms to be listed 919 // first so that they are slightly preferred to the mi forms. 920 def #NAME#16mi8 : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>; 921 def #NAME#32mi8 : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>; 922 def #NAME#64mi8 : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>; 923 924 def #NAME#8mi : BinOpMI_RMW<mnemonic, Xi8 , opnode, MemMRM>; 925 def #NAME#16mi : BinOpMI_RMW<mnemonic, Xi16, opnode, MemMRM>; 926 def #NAME#32mi : BinOpMI_RMW<mnemonic, Xi32, opnode, MemMRM>; 927 def #NAME#64mi32 : BinOpMI_RMW<mnemonic, Xi64, opnode, MemMRM>; 928 929 def #NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL>; 930 def #NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX>; 931 def #NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX>; 932 def #NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX>; 933 } 934 } 935 936 /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is 937 /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and 938 /// SBB. 939 /// 940 /// It would be nice to get rid of the second and third argument here, but 941 /// tblgen can't handle dependent type references aggressively enough: PR8330 942 multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 943 string mnemonic, Format RegMRM, Format MemMRM, 944 SDNode opnode, bit CommutableRR, 945 bit ConvertibleToThreeAddress> { 946 let Defs = [EFLAGS] in { 947 let Constraints = "$src1 = $dst" in { 948 let isCommutable = CommutableRR, 949 isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 950 def #NAME#8rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>; 951 def #NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>; 952 def #NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>; 953 def #NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>; 954 } // isCommutable 955 956 def #NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>; 957 def #NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>; 958 def #NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>; 959 def #NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>; 960 961 def #NAME#8rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>; 962 def #NAME#16rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>; 963 def #NAME#32rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>; 964 def #NAME#64rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>; 965 966 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 967 // NOTE: These are order specific, we want the ri8 forms to be listed 968 // first so that they are slightly preferred to the ri forms. 969 def #NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>; 970 def #NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>; 971 def #NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>; 972 973 def #NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>; 974 def #NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>; 975 def #NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>; 976 def #NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>; 977 } 978 } // Constraints = "$src1 = $dst" 979 980 def #NAME#8mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>; 981 def #NAME#16mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>; 982 def #NAME#32mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>; 983 def #NAME#64mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>; 984 985 // NOTE: These are order specific, we want the mi8 forms to be listed 986 // first so that they are slightly preferred to the mi forms. 987 def #NAME#16mi8 : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>; 988 def #NAME#32mi8 : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>; 989 def #NAME#64mi8 : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>; 990 991 def #NAME#8mi : BinOpMI_RMW_FF<mnemonic, Xi8 , opnode, MemMRM>; 992 def #NAME#16mi : BinOpMI_RMW_FF<mnemonic, Xi16, opnode, MemMRM>; 993 def #NAME#32mi : BinOpMI_RMW_FF<mnemonic, Xi32, opnode, MemMRM>; 994 def #NAME#64mi32 : BinOpMI_RMW_FF<mnemonic, Xi64, opnode, MemMRM>; 995 996 def #NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL>; 997 def #NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX>; 998 def #NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX>; 999 def #NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX>; 1000 } 1001 } 1002 1003 /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is 1004 /// defined with "(set EFLAGS, (...". It would be really nice to find a way 1005 /// to factor this with the other ArithBinOp_*. 1006 /// 1007 multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 1008 string mnemonic, Format RegMRM, Format MemMRM, 1009 SDNode opnode, 1010 bit CommutableRR, bit ConvertibleToThreeAddress> { 1011 let Defs = [EFLAGS] in { 1012 let isCommutable = CommutableRR, 1013 isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1014 def #NAME#8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>; 1015 def #NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>; 1016 def #NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>; 1017 def #NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>; 1018 } // isCommutable 1019 1020 def #NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>; 1021 def #NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>; 1022 def #NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>; 1023 def #NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>; 1024 1025 def #NAME#8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>; 1026 def #NAME#16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>; 1027 def #NAME#32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>; 1028 def #NAME#64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>; 1029 1030 let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 1031 // NOTE: These are order specific, we want the ri8 forms to be listed 1032 // first so that they are slightly preferred to the ri forms. 1033 def #NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>; 1034 def #NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>; 1035 def #NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>; 1036 1037 def #NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>; 1038 def #NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>; 1039 def #NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>; 1040 def #NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>; 1041 } 1042 1043 def #NAME#8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>; 1044 def #NAME#16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>; 1045 def #NAME#32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>; 1046 def #NAME#64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>; 1047 1048 // NOTE: These are order specific, we want the mi8 forms to be listed 1049 // first so that they are slightly preferred to the mi forms. 1050 def #NAME#16mi8 : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>; 1051 def #NAME#32mi8 : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>; 1052 def #NAME#64mi8 : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>; 1053 1054 def #NAME#8mi : BinOpMI_F<mnemonic, Xi8 , opnode, MemMRM>; 1055 def #NAME#16mi : BinOpMI_F<mnemonic, Xi16, opnode, MemMRM>; 1056 def #NAME#32mi : BinOpMI_F<mnemonic, Xi32, opnode, MemMRM>; 1057 def #NAME#64mi32 : BinOpMI_F<mnemonic, Xi64, opnode, MemMRM>; 1058 1059 def #NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL>; 1060 def #NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX>; 1061 def #NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX>; 1062 def #NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX>; 1063 } 1064 } 1065 1066 1067 defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m, 1068 X86and_flag, and, 1, 0>; 1069 defm OR : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m, 1070 X86or_flag, or, 1, 0>; 1071 defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m, 1072 X86xor_flag, xor, 1, 0>; 1073 defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m, 1074 X86add_flag, add, 1, 1>; 1075 defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m, 1076 X86sub_flag, sub, 0, 0>; 1077 1078 // Arithmetic. 1079 let Uses = [EFLAGS] in { 1080 defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag, 1081 1, 0>; 1082 defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag, 1083 0, 0>; 1084 } 1085 1086 defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; 1087 1088 1089 //===----------------------------------------------------------------------===// 1090 // Semantically, test instructions are similar like AND, except they don't 1091 // generate a result. From an encoding perspective, they are very different: 1092 // they don't have all the usual imm8 and REV forms, and are encoded into a 1093 // different space. 1094 def X86testpat : PatFrag<(ops node:$lhs, node:$rhs), 1095 (X86cmp (and_su node:$lhs, node:$rhs), 0)>; 1096 1097 let Defs = [EFLAGS] in { 1098 let isCommutable = 1 in { 1099 def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>; 1100 def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>; 1101 def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>; 1102 def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>; 1103 } // isCommutable 1104 1105 def TEST8rm : BinOpRM_F<0x84, "test", Xi8 , X86testpat>; 1106 def TEST16rm : BinOpRM_F<0x84, "test", Xi16, X86testpat>; 1107 def TEST32rm : BinOpRM_F<0x84, "test", Xi32, X86testpat>; 1108 def TEST64rm : BinOpRM_F<0x84, "test", Xi64, X86testpat>; 1109 1110 def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>; 1111 def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>; 1112 def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>; 1113 def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>; 1114 1115 def TEST8mi : BinOpMI_F<"test", Xi8 , X86testpat, MRM0m, 0xF6>; 1116 def TEST16mi : BinOpMI_F<"test", Xi16, X86testpat, MRM0m, 0xF6>; 1117 def TEST32mi : BinOpMI_F<"test", Xi32, X86testpat, MRM0m, 0xF6>; 1118 def TEST64mi32 : BinOpMI_F<"test", Xi64, X86testpat, MRM0m, 0xF6>; 1119 1120 def TEST8i8 : BinOpAI<0xA8, "test", Xi8 , AL>; 1121 def TEST16i16 : BinOpAI<0xA8, "test", Xi16, AX>; 1122 def TEST32i32 : BinOpAI<0xA8, "test", Xi32, EAX>; 1123 def TEST64i32 : BinOpAI<0xA8, "test", Xi64, RAX>; 1124 } 1125 1126