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