1 //===- subzero/src/IceInstX86.h - Generic x86 instructions -*- C++ -*--===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief This file defines the InstX86Base template class, as well as the 12 /// generic X86 Instruction class hierarchy. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef SUBZERO_SRC_ICEINSTX8632_H 17 #define SUBZERO_SRC_ICEINSTX8632_H 18 19 #include "IceAssemblerX8632.h" 20 #include "IceDefs.h" 21 #include "IceInst.h" 22 #include "IceOperand.h" 23 #include "IceTargetLoweringX86.h" 24 25 namespace Ice { 26 namespace X8632 { 27 28 using Assembler = AssemblerX8632; 29 using AssemblerImmediate = Assembler::Immediate; 30 using TargetLowering = TargetX8632; 31 32 using RegisterSet = ::Ice::RegX8632; 33 using GPRRegister = RegisterSet::GPRRegister; 34 using ByteRegister = RegisterSet::ByteRegister; 35 using XmmRegister = RegisterSet::XmmRegister; 36 37 using Cond = CondX86; 38 using BrCond = Cond::BrCond; 39 using CmppsCond = Cond::CmppsCond; 40 41 template <typename SReg_t, typename DReg_t> 42 using CastEmitterRegOp = Assembler::template CastEmitterRegOp<SReg_t, DReg_t>; 43 template <typename SReg_t, typename DReg_t> 44 using ThreeOpImmEmitter = Assembler::template ThreeOpImmEmitter<SReg_t, DReg_t>; 45 using GPREmitterAddrOp = Assembler::GPREmitterAddrOp; 46 using GPREmitterRegOp = Assembler::GPREmitterRegOp; 47 using GPREmitterShiftD = Assembler::GPREmitterShiftD; 48 using GPREmitterShiftOp = Assembler::GPREmitterShiftOp; 49 using GPREmitterOneOp = Assembler::GPREmitterOneOp; 50 using XmmEmitterRegOp = Assembler::XmmEmitterRegOp; 51 using XmmEmitterShiftOp = Assembler::XmmEmitterShiftOp; 52 using XmmEmitterMovOps = Assembler::XmmEmitterMovOps; 53 54 /// X86Operand extends the Operand hierarchy. Its subclasses are X86OperandMem 55 /// and VariableSplit. 56 class X86Operand : public ::Ice::Operand { 57 X86Operand() = delete; 58 X86Operand(const X86Operand &) = delete; 59 X86Operand &operator=(const X86Operand &) = delete; 60 61 public: 62 enum OperandKindX8632 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit }; 63 using ::Ice::Operand::dump; 64 65 void dump(const Cfg *, Ostream &Str) const override; 66 67 protected: X86Operand(OperandKindX8632 Kind,Type Ty)68 X86Operand(OperandKindX8632 Kind, Type Ty) 69 : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {} 70 }; 71 72 /// X86OperandMem represents the m32 addressing mode, with optional base and 73 /// index registers, a constant offset, and a fixed shift value for the index 74 /// register. 75 class X86OperandMem : public X86Operand { 76 X86OperandMem() = delete; 77 X86OperandMem(const X86OperandMem &) = delete; 78 X86OperandMem &operator=(const X86OperandMem &) = delete; 79 80 public: 81 enum SegmentRegisters { 82 DefaultSegment = -1, 83 #define X(val, name, prefix) val, 84 SEG_REGX8632_TABLE 85 #undef X 86 SegReg_NUM 87 }; 88 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, 89 Constant *Offset, Variable *Index = nullptr, 90 uint16_t Shift = 0, 91 SegmentRegisters SegmentReg = DefaultSegment, 92 bool IsRebased = false) { 93 return new (Func->allocate<X86OperandMem>()) X86OperandMem( 94 Func, Ty, Base, Offset, Index, Shift, SegmentReg, IsRebased); 95 } create(Cfg * Func,Type Ty,Variable * Base,Constant * Offset,bool IsRebased)96 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, 97 Constant *Offset, bool IsRebased) { 98 constexpr Variable *NoIndex = nullptr; 99 constexpr uint16_t NoShift = 0; 100 return new (Func->allocate<X86OperandMem>()) X86OperandMem( 101 Func, Ty, Base, Offset, NoIndex, NoShift, DefaultSegment, IsRebased); 102 } getBase()103 Variable *getBase() const { return Base; } getOffset()104 Constant *getOffset() const { return Offset; } getIndex()105 Variable *getIndex() const { return Index; } getShift()106 uint16_t getShift() const { return Shift; } getSegmentRegister()107 SegmentRegisters getSegmentRegister() const { return SegmentReg; } 108 void emitSegmentOverride(Assembler *Asm) const; getIsRebased()109 bool getIsRebased() const { return IsRebased; } 110 validateMemOperandPIC()111 void validateMemOperandPIC() const { 112 if (!BuildDefs::asserts()) 113 return; 114 const bool HasCR = 115 getOffset() && llvm::isa<ConstantRelocatable>(getOffset()); 116 (void)HasCR; 117 const bool IsRebased = getIsRebased(); 118 (void)IsRebased; 119 assert(!IsRebased); 120 } 121 122 void emit(const Cfg *Func) const override; 123 using X86Operand::dump; 124 void dump(const Cfg *Func, Ostream &Str) const override; 125 classof(const Operand * Operand)126 static bool classof(const Operand *Operand) { 127 return Operand->getKind() == static_cast<OperandKind>(kMem); 128 } 129 130 private: 131 X86OperandMem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, 132 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg, 133 bool IsRebased); 134 135 Variable *const Base; 136 Constant *const Offset; 137 Variable *const Index; 138 const uint16_t Shift; 139 const SegmentRegisters SegmentReg : 16; 140 const bool IsRebased; 141 }; 142 143 /// VariableSplit is a way to treat an f64 memory location as a pair of i32 144 /// locations (Low and High). This is needed for some cases of the Bitcast 145 /// instruction. Since it's not possible for integer registers to access the 146 /// XMM registers and vice versa, the lowering forces the f64 to be spilled to 147 /// the stack and then accesses through the VariableSplit. 148 // TODO(jpp): remove references to VariableSplit from IceInstX86Base as 64bit 149 // targets can natively handle these. 150 class VariableSplit : public X86Operand { 151 VariableSplit() = delete; 152 VariableSplit(const VariableSplit &) = delete; 153 VariableSplit &operator=(const VariableSplit &) = delete; 154 155 public: 156 enum Portion { Low, High }; create(Cfg * Func,Variable * Var,Portion Part)157 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { 158 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); 159 } getVar()160 const Variable *getVar() const { return Var; } getOffset()161 int32_t getOffset() const { return Part == High ? 4 : 0; } 162 163 void emit(const Cfg *Func) const override; 164 using X86Operand::dump; 165 void dump(const Cfg *Func, Ostream &Str) const override; 166 classof(const Operand * Operand)167 static bool classof(const Operand *Operand) { 168 return Operand->getKind() == static_cast<OperandKind>(kSplit); 169 } 170 171 private: VariableSplit(Cfg * Func,Variable * Var,Portion Part)172 VariableSplit(Cfg *Func, Variable *Var, Portion Part) 173 : X86Operand(kSplit, IceType_i32), Var(Var), Part(Part) { 174 assert(Var->getType() == IceType_f64); 175 Vars = Func->allocateArrayOf<Variable *>(1); 176 Vars[0] = Var; 177 NumVars = 1; 178 } 179 180 Variable *Var; 181 Portion Part; 182 }; 183 184 class InstX86Base : public InstTarget { 185 InstX86Base() = delete; 186 InstX86Base(const InstX86Base &) = delete; 187 InstX86Base &operator=(const InstX86Base &) = delete; 188 189 public: 190 enum InstKindX86 { 191 k__Start = Inst::Target, 192 Adc, 193 AdcRMW, 194 Add, 195 AddRMW, 196 Addps, 197 Addss, 198 And, 199 Andnps, 200 Andps, 201 AndRMW, 202 Blendvps, 203 Br, 204 Bsf, 205 Bsr, 206 Bswap, 207 Call, 208 Cbwdq, 209 Cmov, 210 Cmpps, 211 Cmpxchg, 212 Cmpxchg8b, 213 Cvt, 214 Div, 215 Divps, 216 Divss, 217 FakeRMW, 218 Fld, 219 Fstp, 220 Icmp, 221 Idiv, 222 Imul, 223 ImulImm, 224 Insertps, 225 Int3, 226 Jmp, 227 Label, 228 Lea, 229 Load, 230 Mfence, 231 Minps, 232 Maxps, 233 Minss, 234 Maxss, 235 Mov, 236 Movd, 237 Movmsk, 238 Movp, 239 Movq, 240 MovssRegs, 241 Movsx, 242 Movzx, 243 Mul, 244 Mulps, 245 Mulss, 246 Neg, 247 Nop, 248 Or, 249 Orps, 250 OrRMW, 251 Padd, 252 Padds, 253 Paddus, 254 Pand, 255 Pandn, 256 Pblendvb, 257 Pcmpeq, 258 Pcmpgt, 259 Pextr, 260 Pinsr, 261 Pmull, 262 Pmulhw, 263 Pmulhuw, 264 Pmaddwd, 265 Pmuludq, 266 Pop, 267 Por, 268 Pshufb, 269 Pshufd, 270 Punpckl, 271 Punpckh, 272 Packss, 273 Packus, 274 Psll, 275 Psra, 276 Psrl, 277 Psub, 278 Psubs, 279 Psubus, 280 Push, 281 Pxor, 282 Ret, 283 Rol, 284 Round, 285 Sar, 286 Sbb, 287 SbbRMW, 288 Setcc, 289 Shl, 290 Shld, 291 Shr, 292 Shrd, 293 Shufps, 294 Sqrt, 295 Store, 296 StoreP, 297 StoreQ, 298 StoreD, 299 Sub, 300 SubRMW, 301 Subps, 302 Subss, 303 Test, 304 Ucomiss, 305 UD2, 306 Xadd, 307 Xchg, 308 Xor, 309 Xorps, 310 XorRMW, 311 312 /// Intel Architecture Code Analyzer markers. These are not executable so 313 /// must only be used for analysis. 314 IacaStart, 315 IacaEnd 316 }; 317 318 enum SseSuffix { None, Packed, Unpack, Scalar, Integral, Pack }; 319 320 static const char *getWidthString(Type Ty); 321 static const char *getFldString(Type Ty); 322 static const char *getSseSuffixString(Type DestTy, SseSuffix Suffix); 323 static Type getInVectorElementType(Type Ty); 324 static BrCond getOppositeCondition(BrCond Cond); 325 void dump(const Cfg *Func) const override; 326 327 // Shared emit routines for common forms of instructions. 328 void emitTwoAddress(const Cfg *Func, const char *Opcode, 329 const char *Suffix = "") const; 330 getTarget(const Cfg * Func)331 static TargetLowering *getTarget(const Cfg *Func) { 332 return reinterpret_cast<TargetLowering *>(Func->getTarget()); 333 } 334 335 protected: InstX86Base(Cfg * Func,InstKindX86 Kind,SizeT Maxsrcs,Variable * Dest)336 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest) 337 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 338 isClassof(const Inst * Instr,InstKindX86 MyKind)339 static bool isClassof(const Inst *Instr, InstKindX86 MyKind) { 340 return Instr->getKind() == static_cast<InstKind>(MyKind); 341 } 342 // Most instructions that operate on vector arguments require vector memory 343 // operands to be fully aligned (16-byte alignment for PNaCl vector types). 344 // The stack frame layout and call ABI ensure proper alignment for stack 345 // operands, but memory operands (originating from load/store bitcode 346 // instructions) only have element-size alignment guarantees. This function 347 // validates that none of the operands is a memory operand of vector type, 348 // calling report_fatal_error() if one is found. This function should be 349 // called during emission, and maybe also in the ctor (as long as that fits 350 // the lowering style). validateVectorAddrMode()351 void validateVectorAddrMode() const { 352 if (this->getDest()) 353 this->validateVectorAddrModeOpnd(this->getDest()); 354 for (SizeT i = 0; i < this->getSrcSize(); ++i) { 355 this->validateVectorAddrModeOpnd(this->getSrc(i)); 356 } 357 } 358 359 private: validateVectorAddrModeOpnd(const Operand * Opnd)360 static void validateVectorAddrModeOpnd(const Operand *Opnd) { 361 if (llvm::isa<X86OperandMem>(Opnd) && isVectorType(Opnd->getType())) { 362 llvm::report_fatal_error("Possible misaligned vector memory operation"); 363 } 364 } 365 }; 366 367 /// InstX86FakeRMW represents a non-atomic read-modify-write operation on a 368 /// memory location. An InstX86FakeRMW is a "fake" instruction in that it 369 /// still needs to be lowered to some actual RMW instruction. 370 /// 371 /// If A is some memory address, D is some data value to apply, and OP is an 372 /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D 373 class InstX86FakeRMW final : public InstX86Base { 374 InstX86FakeRMW() = delete; 375 InstX86FakeRMW(const InstX86FakeRMW &) = delete; 376 InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete; 377 378 public: 379 static InstX86FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr, 380 Variable *Beacon, InstArithmetic::OpKind Op, 381 uint32_t Align = 1) { 382 // TODO(stichnot): Stop ignoring alignment specification. 383 (void)Align; 384 return new (Func->allocate<InstX86FakeRMW>()) 385 InstX86FakeRMW(Func, Data, Addr, Op, Beacon); 386 } getAddr()387 Operand *getAddr() const { return this->getSrc(1); } getData()388 Operand *getData() const { return this->getSrc(0); } getOp()389 InstArithmetic::OpKind getOp() const { return Op; } getBeacon()390 Variable *getBeacon() const { return llvm::cast<Variable>(this->getSrc(2)); } 391 void dump(const Cfg *Func) const override; classof(const Inst * Instr)392 static bool classof(const Inst *Instr) { 393 return InstX86Base::isClassof(Instr, InstX86Base::FakeRMW); 394 } 395 396 private: 397 InstArithmetic::OpKind Op; 398 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, 399 InstArithmetic::OpKind Op, Variable *Beacon); 400 }; 401 402 /// InstX86Label represents an intra-block label that is the target of an 403 /// intra-block branch. The offset between the label and the branch must be 404 /// fit into one byte (considered "near"). These are used for lowering i1 405 /// calculations, Select instructions, and 64-bit compares on a 32-bit 406 /// architecture, without basic block splitting. Basic block splitting is not 407 /// so desirable for several reasons, one of which is the impact on decisions 408 /// based on whether a variable's live range spans multiple basic blocks. 409 /// 410 /// Intra-block control flow must be used with caution. Consider the sequence 411 /// for "c = (a >= b ? x : y)". 412 /// cmp a, b 413 /// br lt, L1 414 /// mov c, x 415 /// jmp L2 416 /// L1: 417 /// mov c, y 418 /// L2: 419 /// 420 /// Labels L1 and L2 are intra-block labels. Without knowledge of the 421 /// intra-block control flow, liveness analysis will determine the "mov c, x" 422 /// instruction to be dead. One way to prevent this is to insert a 423 /// "FakeUse(c)" instruction anywhere between the two "mov c, ..." 424 /// instructions, e.g.: 425 /// 426 /// cmp a, b 427 /// br lt, L1 428 /// mov c, x 429 /// jmp L2 430 /// FakeUse(c) 431 /// L1: 432 /// mov c, y 433 /// L2: 434 /// 435 /// The down-side is that "mov c, x" can never be dead-code eliminated even if 436 /// there are no uses of c. As unlikely as this situation is, it may be 437 /// prevented by running dead code elimination before lowering. 438 class InstX86Label final : public InstX86Base { 439 InstX86Label() = delete; 440 InstX86Label(const InstX86Label &) = delete; 441 InstX86Label &operator=(const InstX86Label &) = delete; 442 443 public: create(Cfg * Func,TargetLowering * Target)444 static InstX86Label *create(Cfg *Func, TargetLowering *Target) { 445 return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target); 446 } getEmitInstCount()447 uint32_t getEmitInstCount() const override { return 0; } getLabelName()448 GlobalString getLabelName() const { return Name; } getLabelNumber()449 SizeT getLabelNumber() const { return LabelNumber; } isLabel()450 bool isLabel() const override { return true; } 451 void emit(const Cfg *Func) const override; 452 void emitIAS(const Cfg *Func) const override; 453 void dump(const Cfg *Func) const override; setRelocOffset(RelocOffset * Value)454 void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; } 455 456 private: 457 InstX86Label(Cfg *Func, TargetLowering *Target); 458 459 SizeT LabelNumber; // used for unique label generation. 460 RelocOffset *OffsetReloc = nullptr; 461 GlobalString Name; 462 }; 463 464 /// Conditional and unconditional branch instruction. 465 class InstX86Br final : public InstX86Base { 466 InstX86Br() = delete; 467 InstX86Br(const InstX86Br &) = delete; 468 InstX86Br &operator=(const InstX86Br &) = delete; 469 470 public: 471 enum Mode { Near, Far }; 472 473 /// Create a conditional branch to a node. create(Cfg * Func,CfgNode * TargetTrue,CfgNode * TargetFalse,BrCond Condition,Mode Kind)474 static InstX86Br *create(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse, 475 BrCond Condition, Mode Kind) { 476 assert(Condition != Cond::Br_None); 477 constexpr InstX86Label *NoLabel = nullptr; 478 return new (Func->allocate<InstX86Br>()) 479 InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind); 480 } 481 /// Create an unconditional branch to a node. create(Cfg * Func,CfgNode * Target,Mode Kind)482 static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) { 483 constexpr CfgNode *NoCondTarget = nullptr; 484 constexpr InstX86Label *NoLabel = nullptr; 485 return new (Func->allocate<InstX86Br>()) 486 InstX86Br(Func, NoCondTarget, Target, NoLabel, Cond::Br_None, Kind); 487 } 488 /// Create a non-terminator conditional branch to a node, with a fallthrough 489 /// to the next instruction in the current node. This is used for switch 490 /// lowering. create(Cfg * Func,CfgNode * Target,BrCond Condition,Mode Kind)491 static InstX86Br *create(Cfg *Func, CfgNode *Target, BrCond Condition, 492 Mode Kind) { 493 assert(Condition != Cond::Br_None); 494 constexpr CfgNode *NoUncondTarget = nullptr; 495 constexpr InstX86Label *NoLabel = nullptr; 496 return new (Func->allocate<InstX86Br>()) 497 InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind); 498 } 499 /// Create a conditional intra-block branch (or unconditional, if 500 /// Condition==Br_None) to a label in the current block. create(Cfg * Func,InstX86Label * Label,BrCond Condition,Mode Kind)501 static InstX86Br *create(Cfg *Func, InstX86Label *Label, BrCond Condition, 502 Mode Kind) { 503 constexpr CfgNode *NoCondTarget = nullptr; 504 constexpr CfgNode *NoUncondTarget = nullptr; 505 return new (Func->allocate<InstX86Br>()) 506 InstX86Br(Func, NoCondTarget, NoUncondTarget, Label, Condition, Kind); 507 } getTargetTrue()508 const CfgNode *getTargetTrue() const { return TargetTrue; } getTargetFalse()509 const CfgNode *getTargetFalse() const { return TargetFalse; } isNear()510 bool isNear() const { return Kind == Near; } 511 bool optimizeBranch(const CfgNode *NextNode); getEmitInstCount()512 uint32_t getEmitInstCount() const override { 513 uint32_t Sum = 0; 514 if (Label) 515 ++Sum; 516 if (getTargetTrue()) 517 ++Sum; 518 if (getTargetFalse()) 519 ++Sum; 520 return Sum; 521 } isUnconditionalBranch()522 bool isUnconditionalBranch() const override { 523 return !Label && Condition == Cond::Br_None; 524 } getIntraBlockBranchTarget()525 const Inst *getIntraBlockBranchTarget() const override { return Label; } 526 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; 527 void emit(const Cfg *Func) const override; 528 void emitIAS(const Cfg *Func) const override; 529 void dump(const Cfg *Func) const override; classof(const Inst * Instr)530 static bool classof(const Inst *Instr) { 531 return InstX86Base::isClassof(Instr, InstX86Base::Br); 532 } 533 534 private: 535 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 536 const InstX86Label *Label, BrCond Condition, Mode Kind); 537 538 BrCond Condition; 539 const CfgNode *TargetTrue; 540 const CfgNode *TargetFalse; 541 const InstX86Label *Label; // Intra-block branch target 542 const Mode Kind; 543 }; 544 545 /// Jump to a target outside this function, such as tailcall, nacljump, 546 /// naclret, unreachable. This is different from a Branch instruction in that 547 /// there is no intra-function control flow to represent. 548 class InstX86Jmp final : public InstX86Base { 549 InstX86Jmp() = delete; 550 InstX86Jmp(const InstX86Jmp &) = delete; 551 InstX86Jmp &operator=(const InstX86Jmp &) = delete; 552 553 public: create(Cfg * Func,Operand * Target)554 static InstX86Jmp *create(Cfg *Func, Operand *Target) { 555 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target); 556 } getJmpTarget()557 Operand *getJmpTarget() const { return this->getSrc(0); } 558 void emit(const Cfg *Func) const override; 559 void emitIAS(const Cfg *Func) const override; 560 void dump(const Cfg *Func) const override; classof(const Inst * Instr)561 static bool classof(const Inst *Instr) { 562 return InstX86Base::isClassof(Instr, InstX86Base::Jmp); 563 } 564 565 private: 566 InstX86Jmp(Cfg *Func, Operand *Target); 567 }; 568 569 /// Call instruction. Arguments should have already been pushed. 570 class InstX86Call final : public InstX86Base { 571 InstX86Call() = delete; 572 InstX86Call(const InstX86Call &) = delete; 573 InstX86Call &operator=(const InstX86Call &) = delete; 574 575 public: create(Cfg * Func,Variable * Dest,Operand * CallTarget)576 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 577 return new (Func->allocate<InstX86Call>()) 578 InstX86Call(Func, Dest, CallTarget); 579 } getCallTarget()580 Operand *getCallTarget() const { return this->getSrc(0); } 581 void emit(const Cfg *Func) const override; 582 void emitIAS(const Cfg *Func) const override; 583 void dump(const Cfg *Func) const override; classof(const Inst * Instr)584 static bool classof(const Inst *Instr) { 585 return InstX86Base::isClassof(Instr, InstX86Base::Call); 586 } 587 588 private: 589 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 590 }; 591 592 /// Emit a one-operand (GPR) instruction. 593 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 594 const GPREmitterOneOp &Emitter); 595 596 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0, 597 const Operand *Op1, const GPREmitterAddrOp &Emitter); 598 599 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 600 const Operand *Src, const GPREmitterShiftOp &Emitter); 601 602 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const AsmAddress &Addr, 603 const Operand *Src, const GPREmitterAddrOp &Emitter); 604 605 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 606 const Operand *Src, const XmmEmitterRegOp &Emitter); 607 608 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, 609 const Operand *Src1Op, const Operand *Src2Op, 610 const GPREmitterShiftD &Emitter); 611 612 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT), 613 SReg_t (*srcEnc)(RegNumT)> 614 void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest, 615 Type SrcTy, const Operand *Src, 616 const CastEmitterRegOp<DReg_t, SReg_t> &Emitter); 617 618 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT), 619 SReg_t (*srcEnc)(RegNumT)> 620 void emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, 621 const Variable *Dest, const Operand *Src0, 622 const Operand *Src1, 623 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter); 624 625 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, 626 const Operand *Src, const XmmEmitterMovOps Emitter); 627 628 void emitVariableBlendInst(const char *Opcode, const Inst *Instr, 629 const Cfg *Func); 630 631 void emitIASVariableBlendInst(const Inst *Instr, const Cfg *Func, 632 const XmmEmitterRegOp &Emitter); 633 634 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 635 const Operand *Src, const XmmEmitterShiftOp &Emitter); 636 637 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable 638 /// that's guaranteed to be a register. 639 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> 640 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, 641 const Operand *Src, const GPREmitterRegOp &Emitter); 642 643 /// Instructions of the form x := op(x). 644 template <typename InstX86Base::InstKindX86 K> 645 class InstX86BaseInplaceopGPR : public InstX86Base { 646 InstX86BaseInplaceopGPR() = delete; 647 InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete; 648 InstX86BaseInplaceopGPR &operator=(const InstX86BaseInplaceopGPR &) = delete; 649 650 public: 651 using Base = InstX86BaseInplaceopGPR<K>; 652 emit(const Cfg * Func)653 void emit(const Cfg *Func) const override { 654 if (!BuildDefs::dump()) 655 return; 656 Ostream &Str = Func->getContext()->getStrEmit(); 657 assert(this->getSrcSize() == 1); 658 Str << "\t" << Opcode << "\t"; 659 this->getSrc(0)->emit(Func); 660 } emitIAS(const Cfg * Func)661 void emitIAS(const Cfg *Func) const override { 662 assert(this->getSrcSize() == 1); 663 const Variable *Var = this->getDest(); 664 Type Ty = Var->getType(); 665 emitIASOpTyGPR(Func, Ty, Var, Emitter); 666 } dump(const Cfg * Func)667 void dump(const Cfg *Func) const override { 668 if (!BuildDefs::dump()) 669 return; 670 Ostream &Str = Func->getContext()->getStrDump(); 671 this->dumpDest(Func); 672 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 673 this->dumpSources(Func); 674 } classof(const Inst * Instr)675 static bool classof(const Inst *Instr) { 676 return InstX86Base::isClassof(Instr, K); 677 } 678 679 protected: InstX86BaseInplaceopGPR(Cfg * Func,Operand * SrcDest)680 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest) 681 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 682 this->addSource(SrcDest); 683 } 684 685 private: 686 static const char *const Opcode; 687 static const GPREmitterOneOp Emitter; 688 }; 689 690 /// Instructions of the form x := op(y). 691 template <typename InstX86Base::InstKindX86 K> 692 class InstX86BaseUnaryopGPR : public InstX86Base { 693 InstX86BaseUnaryopGPR() = delete; 694 InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete; 695 InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete; 696 697 public: 698 using Base = InstX86BaseUnaryopGPR<K>; 699 emit(const Cfg * Func)700 void emit(const Cfg *Func) const override { 701 if (!BuildDefs::dump()) 702 return; 703 Ostream &Str = Func->getContext()->getStrEmit(); 704 assert(this->getSrcSize() == 1); 705 Type SrcTy = this->getSrc(0)->getType(); 706 Type DestTy = this->getDest()->getType(); 707 Str << "\t" << Opcode << this->getWidthString(SrcTy); 708 // Movsx and movzx need both the source and dest type width letter to 709 // define the operation. The other unary operations have the same source 710 // and dest type and as a result need only one letter. 711 if (SrcTy != DestTy) 712 Str << this->getWidthString(DestTy); 713 Str << "\t"; 714 this->getSrc(0)->emit(Func); 715 Str << ", "; 716 this->getDest()->emit(Func); 717 } emitIAS(const Cfg * Func)718 void emitIAS(const Cfg *Func) const override { 719 assert(this->getSrcSize() == 1 && K != InstX86Base::Lea); 720 const Variable *Var = this->getDest(); 721 Type Ty = Var->getType(); 722 const Operand *Src = this->getSrc(0); 723 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); 724 } dump(const Cfg * Func)725 void dump(const Cfg *Func) const override { 726 if (!BuildDefs::dump()) 727 return; 728 Ostream &Str = Func->getContext()->getStrDump(); 729 this->dumpDest(Func); 730 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; 731 this->dumpSources(Func); 732 } 733 classof(const Inst * Instr)734 static bool classof(const Inst *Instr) { 735 return InstX86Base::isClassof(Instr, K); 736 } 737 738 protected: InstX86BaseUnaryopGPR(Cfg * Func,Variable * Dest,Operand * Src)739 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) 740 : InstX86Base(Func, K, 1, Dest) { 741 this->addSource(Src); 742 } 743 744 static const char *const Opcode; 745 static const GPREmitterRegOp Emitter; 746 }; 747 748 template <typename InstX86Base::InstKindX86 K> 749 class InstX86BaseUnaryopXmm : public InstX86Base { 750 InstX86BaseUnaryopXmm() = delete; 751 InstX86BaseUnaryopXmm(const InstX86BaseUnaryopXmm &) = delete; 752 InstX86BaseUnaryopXmm &operator=(const InstX86BaseUnaryopXmm &) = delete; 753 754 public: 755 using Base = InstX86BaseUnaryopXmm<K>; 756 emit(const Cfg * Func)757 void emit(const Cfg *Func) const override { 758 if (!BuildDefs::dump()) 759 return; 760 Ostream &Str = Func->getContext()->getStrEmit(); 761 assert(this->getSrcSize() == 1); 762 Str << "\t" << Opcode << "\t"; 763 this->getSrc(0)->emit(Func); 764 Str << ", "; 765 this->getDest()->emit(Func); 766 } emitIAS(const Cfg * Func)767 void emitIAS(const Cfg *Func) const override { 768 Type Ty = this->getDest()->getType(); 769 assert(this->getSrcSize() == 1); 770 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter); 771 } dump(const Cfg * Func)772 void dump(const Cfg *Func) const override { 773 if (!BuildDefs::dump()) 774 return; 775 Ostream &Str = Func->getContext()->getStrDump(); 776 this->dumpDest(Func); 777 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 778 this->dumpSources(Func); 779 } classof(const Inst * Instr)780 static bool classof(const Inst *Instr) { 781 return InstX86Base::isClassof(Instr, K); 782 } 783 784 protected: InstX86BaseUnaryopXmm(Cfg * Func,Variable * Dest,Operand * Src)785 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) 786 : InstX86Base(Func, K, 1, Dest) { 787 this->addSource(Src); 788 } 789 790 static const char *const Opcode; 791 static const XmmEmitterRegOp Emitter; 792 }; 793 794 template <typename InstX86Base::InstKindX86 K> 795 class InstX86BaseBinopGPRShift : public InstX86Base { 796 InstX86BaseBinopGPRShift() = delete; 797 InstX86BaseBinopGPRShift(const InstX86BaseBinopGPRShift &) = delete; 798 InstX86BaseBinopGPRShift & 799 operator=(const InstX86BaseBinopGPRShift &) = delete; 800 801 public: 802 using Base = InstX86BaseBinopGPRShift<K>; 803 emit(const Cfg * Func)804 void emit(const Cfg *Func) const override { 805 if (!BuildDefs::dump()) 806 return; 807 this->emitTwoAddress(Func, Opcode); 808 } emitIAS(const Cfg * Func)809 void emitIAS(const Cfg *Func) const override { 810 Type Ty = this->getDest()->getType(); 811 assert(this->getSrcSize() == 2); 812 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter); 813 } dump(const Cfg * Func)814 void dump(const Cfg *Func) const override { 815 if (!BuildDefs::dump()) 816 return; 817 Ostream &Str = Func->getContext()->getStrDump(); 818 this->dumpDest(Func); 819 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 820 this->dumpSources(Func); 821 } classof(const Inst * Instr)822 static bool classof(const Inst *Instr) { 823 return InstX86Base::isClassof(Instr, K); 824 } 825 826 protected: InstX86BaseBinopGPRShift(Cfg * Func,Variable * Dest,Operand * Source)827 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) 828 : InstX86Base(Func, K, 2, Dest) { 829 this->addSource(Dest); 830 this->addSource(Source); 831 } 832 833 static const char *const Opcode; 834 static const GPREmitterShiftOp Emitter; 835 }; 836 837 template <typename InstX86Base::InstKindX86 K> 838 class InstX86BaseBinopGPR : public InstX86Base { 839 InstX86BaseBinopGPR() = delete; 840 InstX86BaseBinopGPR(const InstX86BaseBinopGPR &) = delete; 841 InstX86BaseBinopGPR &operator=(const InstX86BaseBinopGPR &) = delete; 842 843 public: 844 using Base = InstX86BaseBinopGPR<K>; 845 emit(const Cfg * Func)846 void emit(const Cfg *Func) const override { 847 if (!BuildDefs::dump()) 848 return; 849 this->emitTwoAddress(Func, Opcode); 850 } emitIAS(const Cfg * Func)851 void emitIAS(const Cfg *Func) const override { 852 Type Ty = this->getDest()->getType(); 853 assert(this->getSrcSize() == 2); 854 static_assert(K != InstX86Base::Lea, "Lea should be a unaryop."); 855 emitIASRegOpTyGPR(Func, Ty, this->getDest(), this->getSrc(1), Emitter); 856 } dump(const Cfg * Func)857 void dump(const Cfg *Func) const override { 858 if (!BuildDefs::dump()) 859 return; 860 Ostream &Str = Func->getContext()->getStrDump(); 861 this->dumpDest(Func); 862 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 863 this->dumpSources(Func); 864 } classof(const Inst * Instr)865 static bool classof(const Inst *Instr) { 866 return InstX86Base::isClassof(Instr, K); 867 } 868 869 protected: InstX86BaseBinopGPR(Cfg * Func,Variable * Dest,Operand * Source)870 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source) 871 : InstX86Base(Func, K, 2, Dest) { 872 this->addSource(Dest); 873 this->addSource(Source); 874 } 875 876 static const char *const Opcode; 877 static const GPREmitterRegOp Emitter; 878 }; 879 880 template <typename InstX86Base::InstKindX86 K> 881 class InstX86BaseBinopRMW : public InstX86Base { 882 InstX86BaseBinopRMW() = delete; 883 InstX86BaseBinopRMW(const InstX86BaseBinopRMW &) = delete; 884 InstX86BaseBinopRMW &operator=(const InstX86BaseBinopRMW &) = delete; 885 886 public: 887 using Base = InstX86BaseBinopRMW<K>; 888 emit(const Cfg * Func)889 void emit(const Cfg *Func) const override { 890 if (!BuildDefs::dump()) 891 return; 892 this->emitTwoAddress(Func, Opcode); 893 } emitIAS(const Cfg * Func)894 void emitIAS(const Cfg *Func) const override { 895 Type Ty = this->getSrc(0)->getType(); 896 assert(this->getSrcSize() == 2); 897 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter); 898 } dump(const Cfg * Func)899 void dump(const Cfg *Func) const override { 900 if (!BuildDefs::dump()) 901 return; 902 Ostream &Str = Func->getContext()->getStrDump(); 903 Str << Opcode << "." << this->getSrc(0)->getType() << " "; 904 this->dumpSources(Func); 905 } classof(const Inst * Instr)906 static bool classof(const Inst *Instr) { 907 return InstX86Base::isClassof(Instr, K); 908 } 909 910 protected: InstX86BaseBinopRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)911 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 912 : InstX86Base(Func, K, 2, nullptr) { 913 this->addSource(DestSrc0); 914 this->addSource(Src1); 915 } 916 917 static const char *const Opcode; 918 static const GPREmitterAddrOp Emitter; 919 }; 920 921 template <typename InstX86Base::InstKindX86 K, bool NeedsElementType, 922 typename InstX86Base::SseSuffix Suffix> 923 class InstX86BaseBinopXmm : public InstX86Base { 924 InstX86BaseBinopXmm() = delete; 925 InstX86BaseBinopXmm(const InstX86BaseBinopXmm &) = delete; 926 InstX86BaseBinopXmm &operator=(const InstX86BaseBinopXmm &) = delete; 927 928 public: 929 using Base = InstX86BaseBinopXmm<K, NeedsElementType, Suffix>; 930 emit(const Cfg * Func)931 void emit(const Cfg *Func) const override { 932 if (!BuildDefs::dump()) 933 return; 934 this->validateVectorAddrMode(); 935 const Type DestTy = ArithmeticTypeOverride == IceType_void 936 ? this->getDest()->getType() 937 : ArithmeticTypeOverride; 938 const char *SuffixString = getSseSuffixString(DestTy, Suffix); 939 this->emitTwoAddress(Func, Opcode, SuffixString); 940 } emitIAS(const Cfg * Func)941 void emitIAS(const Cfg *Func) const override { 942 this->validateVectorAddrMode(); 943 Type Ty = this->getDest()->getType(); 944 if (NeedsElementType) 945 Ty = typeElementType(Ty); 946 assert(this->getSrcSize() == 2); 947 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter); 948 } dump(const Cfg * Func)949 void dump(const Cfg *Func) const override { 950 if (!BuildDefs::dump()) 951 return; 952 Ostream &Str = Func->getContext()->getStrDump(); 953 this->dumpDest(Func); 954 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 955 this->dumpSources(Func); 956 } classof(const Inst * Instr)957 static bool classof(const Inst *Instr) { 958 return InstX86Base::isClassof(Instr, K); 959 } 960 961 protected: 962 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source, 963 Type ArithmeticTypeOverride = IceType_void) 964 : InstX86Base(Func, K, 2, Dest), 965 ArithmeticTypeOverride(ArithmeticTypeOverride) { 966 this->addSource(Dest); 967 this->addSource(Source); 968 } 969 970 const Type ArithmeticTypeOverride; 971 static const char *const Opcode; 972 static const XmmEmitterRegOp Emitter; 973 }; 974 975 template <typename InstX86Base::InstKindX86 K, bool AllowAllTypes = false> 976 class InstX86BaseBinopXmmShift : public InstX86Base { 977 InstX86BaseBinopXmmShift() = delete; 978 InstX86BaseBinopXmmShift(const InstX86BaseBinopXmmShift &) = delete; 979 InstX86BaseBinopXmmShift & 980 operator=(const InstX86BaseBinopXmmShift &) = delete; 981 982 public: 983 using Base = InstX86BaseBinopXmmShift<K, AllowAllTypes>; 984 emit(const Cfg * Func)985 void emit(const Cfg *Func) const override { 986 if (!BuildDefs::dump()) 987 return; 988 this->validateVectorAddrMode(); 989 // Shift operations are always integral, and hence always need a suffix. 990 const Type DestTy = this->getDest()->getType(); 991 const char *SuffixString = getSseSuffixString(DestTy, SseSuffix::Integral); 992 this->emitTwoAddress(Func, this->Opcode, SuffixString); 993 } emitIAS(const Cfg * Func)994 void emitIAS(const Cfg *Func) const override { 995 this->validateVectorAddrMode(); 996 Type Ty = this->getDest()->getType(); 997 assert(AllowAllTypes || isVectorType(Ty)); 998 Type ElementTy = typeElementType(Ty); 999 assert(this->getSrcSize() == 2); 1000 emitIASXmmShift(Func, ElementTy, this->getDest(), this->getSrc(1), Emitter); 1001 } dump(const Cfg * Func)1002 void dump(const Cfg *Func) const override { 1003 if (!BuildDefs::dump()) 1004 return; 1005 Ostream &Str = Func->getContext()->getStrDump(); 1006 this->dumpDest(Func); 1007 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 1008 this->dumpSources(Func); 1009 } classof(const Inst * Instr)1010 static bool classof(const Inst *Instr) { 1011 return InstX86Base::isClassof(Instr, K); 1012 } 1013 1014 protected: InstX86BaseBinopXmmShift(Cfg * Func,Variable * Dest,Operand * Source)1015 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) 1016 : InstX86Base(Func, K, 2, Dest) { 1017 this->addSource(Dest); 1018 this->addSource(Source); 1019 } 1020 1021 static const char *const Opcode; 1022 static const XmmEmitterShiftOp Emitter; 1023 }; 1024 1025 template <typename InstX86Base::InstKindX86 K> 1026 class InstX86BaseTernop : public InstX86Base { 1027 InstX86BaseTernop() = delete; 1028 InstX86BaseTernop(const InstX86BaseTernop &) = delete; 1029 InstX86BaseTernop &operator=(const InstX86BaseTernop &) = delete; 1030 1031 public: 1032 using Base = InstX86BaseTernop<K>; 1033 emit(const Cfg * Func)1034 void emit(const Cfg *Func) const override { 1035 if (!BuildDefs::dump()) 1036 return; 1037 Ostream &Str = Func->getContext()->getStrEmit(); 1038 assert(this->getSrcSize() == 3); 1039 Str << "\t" << Opcode << "\t"; 1040 this->getSrc(2)->emit(Func); 1041 Str << ", "; 1042 this->getSrc(1)->emit(Func); 1043 Str << ", "; 1044 this->getDest()->emit(Func); 1045 } dump(const Cfg * Func)1046 void dump(const Cfg *Func) const override { 1047 if (!BuildDefs::dump()) 1048 return; 1049 Ostream &Str = Func->getContext()->getStrDump(); 1050 this->dumpDest(Func); 1051 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 1052 this->dumpSources(Func); 1053 } classof(const Inst * Instr)1054 static bool classof(const Inst *Instr) { 1055 return InstX86Base::isClassof(Instr, K); 1056 } 1057 1058 protected: InstX86BaseTernop(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)1059 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1, 1060 Operand *Source2) 1061 : InstX86Base(Func, K, 3, Dest) { 1062 this->addSource(Dest); 1063 this->addSource(Source1); 1064 this->addSource(Source2); 1065 } 1066 1067 static const char *const Opcode; 1068 }; 1069 1070 // Instructions of the form x := y op z 1071 template <typename InstX86Base::InstKindX86 K> 1072 class InstX86BaseThreeAddressop : public InstX86Base { 1073 InstX86BaseThreeAddressop() = delete; 1074 InstX86BaseThreeAddressop(const InstX86BaseThreeAddressop &) = delete; 1075 InstX86BaseThreeAddressop & 1076 operator=(const InstX86BaseThreeAddressop &) = delete; 1077 1078 public: 1079 using Base = InstX86BaseThreeAddressop<K>; 1080 emit(const Cfg * Func)1081 void emit(const Cfg *Func) const override { 1082 if (!BuildDefs::dump()) 1083 return; 1084 Ostream &Str = Func->getContext()->getStrEmit(); 1085 assert(this->getSrcSize() == 2); 1086 Str << "\t" << Opcode << "\t"; 1087 this->getSrc(1)->emit(Func); 1088 Str << ", "; 1089 this->getSrc(0)->emit(Func); 1090 Str << ", "; 1091 this->getDest()->emit(Func); 1092 } dump(const Cfg * Func)1093 void dump(const Cfg *Func) const override { 1094 if (!BuildDefs::dump()) 1095 return; 1096 Ostream &Str = Func->getContext()->getStrDump(); 1097 this->dumpDest(Func); 1098 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 1099 this->dumpSources(Func); 1100 } classof(const Inst * Instr)1101 static bool classof(const Inst *Instr) { 1102 return InstX86Base::isClassof(Instr, K); 1103 } 1104 1105 protected: InstX86BaseThreeAddressop(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)1106 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, 1107 Operand *Source1) 1108 : InstX86Base(Func, K, 2, Dest) { 1109 this->addSource(Source0); 1110 this->addSource(Source1); 1111 } 1112 1113 static const char *const Opcode; 1114 }; 1115 1116 /// Base class for assignment instructions 1117 template <typename InstX86Base::InstKindX86 K> 1118 class InstX86BaseMovlike : public InstX86Base { 1119 InstX86BaseMovlike() = delete; 1120 InstX86BaseMovlike(const InstX86BaseMovlike &) = delete; 1121 InstX86BaseMovlike &operator=(const InstX86BaseMovlike &) = delete; 1122 1123 public: 1124 using Base = InstX86BaseMovlike<K>; 1125 isRedundantAssign()1126 bool isRedundantAssign() const override { 1127 if (const auto *SrcVar = llvm::dyn_cast<const Variable>(this->getSrc(0))) { 1128 if (SrcVar->hasReg() && this->Dest->hasReg()) { 1129 // An assignment between physical registers is considered redundant if 1130 // they have the same base register and the same encoding. E.g.: 1131 // mov cl, ecx ==> redundant 1132 // mov ch, ecx ==> not redundant due to different encodings 1133 // mov ch, ebp ==> not redundant due to different base registers 1134 // mov ecx, ecx ==> redundant, and dangerous in x86-64. i64 zexting 1135 // is handled by Inst86Zext. 1136 const auto SrcReg = SrcVar->getRegNum(); 1137 const auto DestReg = this->Dest->getRegNum(); 1138 return (RegX8632::getEncoding(SrcReg) == 1139 RegX8632::getEncoding(DestReg)) && 1140 (RegX8632::getBaseReg(SrcReg) == RegX8632::getBaseReg(DestReg)); 1141 } 1142 } 1143 return checkForRedundantAssign(this->getDest(), this->getSrc(0)); 1144 } isVarAssign()1145 bool isVarAssign() const override { 1146 return llvm::isa<Variable>(this->getSrc(0)); 1147 } dump(const Cfg * Func)1148 void dump(const Cfg *Func) const override { 1149 if (!BuildDefs::dump()) 1150 return; 1151 Ostream &Str = Func->getContext()->getStrDump(); 1152 Str << Opcode << "." << this->getDest()->getType() << " "; 1153 this->dumpDest(Func); 1154 Str << ", "; 1155 this->dumpSources(Func); 1156 } classof(const Inst * Instr)1157 static bool classof(const Inst *Instr) { 1158 return InstX86Base::isClassof(Instr, K); 1159 } 1160 1161 protected: InstX86BaseMovlike(Cfg * Func,Variable * Dest,Operand * Source)1162 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source) 1163 : InstX86Base(Func, K, 1, Dest) { 1164 this->addSource(Source); 1165 // For an integer assignment, make sure it's either a same-type assignment 1166 // or a truncation. 1167 assert(!isScalarIntegerType(Dest->getType()) || 1168 (typeWidthInBytes(Dest->getType()) <= 1169 typeWidthInBytes(Source->getType()))); 1170 } 1171 1172 static const char *const Opcode; 1173 }; 1174 1175 class InstX86Bswap : public InstX86BaseInplaceopGPR<InstX86Base::Bswap> { 1176 public: create(Cfg * Func,Operand * SrcDest)1177 static InstX86Bswap *create(Cfg *Func, Operand *SrcDest) { 1178 return new (Func->allocate<InstX86Bswap>()) InstX86Bswap(Func, SrcDest); 1179 } 1180 1181 private: InstX86Bswap(Cfg * Func,Operand * SrcDest)1182 InstX86Bswap(Cfg *Func, Operand *SrcDest) 1183 : InstX86BaseInplaceopGPR<InstX86Base::Bswap>(Func, SrcDest) {} 1184 }; 1185 1186 class InstX86Neg : public InstX86BaseInplaceopGPR<InstX86Base::Neg> { 1187 public: create(Cfg * Func,Operand * SrcDest)1188 static InstX86Neg *create(Cfg *Func, Operand *SrcDest) { 1189 return new (Func->allocate<InstX86Neg>()) InstX86Neg(Func, SrcDest); 1190 } 1191 1192 private: InstX86Neg(Cfg * Func,Operand * SrcDest)1193 InstX86Neg(Cfg *Func, Operand *SrcDest) 1194 : InstX86BaseInplaceopGPR<InstX86Base::Neg>(Func, SrcDest) {} 1195 }; 1196 1197 class InstX86Bsf : public InstX86BaseUnaryopGPR<InstX86Base::Bsf> { 1198 public: create(Cfg * Func,Variable * Dest,Operand * Src)1199 static InstX86Bsf *create(Cfg *Func, Variable *Dest, Operand *Src) { 1200 return new (Func->allocate<InstX86Bsf>()) InstX86Bsf(Func, Dest, Src); 1201 } 1202 1203 private: InstX86Bsf(Cfg * Func,Variable * Dest,Operand * Src)1204 InstX86Bsf(Cfg *Func, Variable *Dest, Operand *Src) 1205 : InstX86BaseUnaryopGPR<InstX86Base::Bsf>(Func, Dest, Src) {} 1206 }; 1207 1208 class InstX86Bsr : public InstX86BaseUnaryopGPR<InstX86Base::Bsr> { 1209 public: create(Cfg * Func,Variable * Dest,Operand * Src)1210 static InstX86Bsr *create(Cfg *Func, Variable *Dest, Operand *Src) { 1211 return new (Func->allocate<InstX86Bsr>()) InstX86Bsr(Func, Dest, Src); 1212 } 1213 1214 private: InstX86Bsr(Cfg * Func,Variable * Dest,Operand * Src)1215 InstX86Bsr(Cfg *Func, Variable *Dest, Operand *Src) 1216 : InstX86BaseUnaryopGPR<InstX86Base::Bsr>(Func, Dest, Src) {} 1217 }; 1218 1219 class InstX86Lea : public InstX86BaseUnaryopGPR<InstX86Base::Lea> { 1220 public: create(Cfg * Func,Variable * Dest,Operand * Src)1221 static InstX86Lea *create(Cfg *Func, Variable *Dest, Operand *Src) { 1222 return new (Func->allocate<InstX86Lea>()) InstX86Lea(Func, Dest, Src); 1223 } 1224 1225 void emit(const Cfg *Func) const override; 1226 void emitIAS(const Cfg *Func) const override; 1227 1228 private: InstX86Lea(Cfg * Func,Variable * Dest,Operand * Src)1229 InstX86Lea(Cfg *Func, Variable *Dest, Operand *Src) 1230 : InstX86BaseUnaryopGPR<InstX86Base::Lea>(Func, Dest, Src) {} 1231 1232 Inst *deoptToAddOrNull(const Cfg *Func) const; 1233 }; 1234 1235 // Cbwdq instruction - wrapper for cbw, cwd, and cdq 1236 class InstX86Cbwdq : public InstX86BaseUnaryopGPR<InstX86Base::Cbwdq> { 1237 public: create(Cfg * Func,Variable * Dest,Operand * Src)1238 static InstX86Cbwdq *create(Cfg *Func, Variable *Dest, Operand *Src) { 1239 return new (Func->allocate<InstX86Cbwdq>()) InstX86Cbwdq(Func, Dest, Src); 1240 } 1241 1242 void emit(const Cfg *Func) const override; 1243 void emitIAS(const Cfg *Func) const override; 1244 1245 private: InstX86Cbwdq(Cfg * Func,Variable * Dest,Operand * Src)1246 InstX86Cbwdq(Cfg *Func, Variable *Dest, Operand *Src) 1247 : InstX86BaseUnaryopGPR<InstX86Base::Cbwdq>(Func, Dest, Src) {} 1248 }; 1249 1250 class InstX86Movsx : public InstX86BaseUnaryopGPR<InstX86Base::Movsx> { 1251 public: create(Cfg * Func,Variable * Dest,Operand * Src)1252 static InstX86Movsx *create(Cfg *Func, Variable *Dest, Operand *Src) { 1253 assert(typeWidthInBytes(Dest->getType()) > 1254 typeWidthInBytes(Src->getType())); 1255 return new (Func->allocate<InstX86Movsx>()) InstX86Movsx(Func, Dest, Src); 1256 } 1257 1258 void emitIAS(const Cfg *Func) const override; 1259 1260 private: InstX86Movsx(Cfg * Func,Variable * Dest,Operand * Src)1261 InstX86Movsx(Cfg *Func, Variable *Dest, Operand *Src) 1262 : InstX86BaseUnaryopGPR<InstX86Base::Movsx>(Func, Dest, Src) {} 1263 }; 1264 1265 class InstX86Movzx : public InstX86BaseUnaryopGPR<InstX86Base::Movzx> { 1266 public: create(Cfg * Func,Variable * Dest,Operand * Src)1267 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) { 1268 assert(typeWidthInBytes(Dest->getType()) > 1269 typeWidthInBytes(Src->getType())); 1270 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src); 1271 } 1272 1273 void emit(const Cfg *Func) const override; 1274 1275 void emitIAS(const Cfg *Func) const override; 1276 setMustKeep()1277 void setMustKeep() { MustKeep = true; } 1278 1279 private: 1280 bool MustKeep = false; 1281 InstX86Movzx(Cfg * Func,Variable * Dest,Operand * Src)1282 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src) 1283 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {} 1284 }; 1285 1286 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> { 1287 public: create(Cfg * Func,Variable * Dest,Operand * Src)1288 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) { 1289 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src); 1290 } 1291 1292 void emit(const Cfg *Func) const override; 1293 1294 void emitIAS(const Cfg *Func) const override; 1295 1296 private: InstX86Movd(Cfg * Func,Variable * Dest,Operand * Src)1297 InstX86Movd(Cfg *Func, Variable *Dest, Operand *Src) 1298 : InstX86BaseUnaryopXmm<InstX86Base::Movd>(Func, Dest, Src) {} 1299 }; 1300 1301 class InstX86Movmsk final : public InstX86Base { 1302 InstX86Movmsk() = delete; 1303 InstX86Movmsk(const InstX86Movmsk &) = delete; 1304 InstX86Movmsk &operator=(const InstX86Movmsk &) = delete; 1305 1306 public: create(Cfg * Func,Variable * Dest,Operand * Source)1307 static InstX86Movmsk *create(Cfg *Func, Variable *Dest, Operand *Source) { 1308 return new (Func->allocate<InstX86Movmsk>()) 1309 InstX86Movmsk(Func, Dest, Source); 1310 } 1311 void emit(const Cfg *Func) const override; 1312 void emitIAS(const Cfg *Func) const override; 1313 void dump(const Cfg *Func) const override; classof(const Inst * Instr)1314 static bool classof(const Inst *Instr) { 1315 return InstX86Base::isClassof(Instr, InstX86Base::Movmsk); 1316 } 1317 1318 private: 1319 InstX86Movmsk(Cfg *Func, Variable *Dest, Operand *Source); 1320 }; 1321 1322 class InstX86Sqrt : public InstX86BaseUnaryopXmm<InstX86Base::Sqrt> { 1323 public: create(Cfg * Func,Variable * Dest,Operand * Src)1324 static InstX86Sqrt *create(Cfg *Func, Variable *Dest, Operand *Src) { 1325 return new (Func->allocate<InstX86Sqrt>()) InstX86Sqrt(Func, Dest, Src); 1326 } 1327 1328 virtual void emit(const Cfg *Func) const override; 1329 1330 private: InstX86Sqrt(Cfg * Func,Variable * Dest,Operand * Src)1331 InstX86Sqrt(Cfg *Func, Variable *Dest, Operand *Src) 1332 : InstX86BaseUnaryopXmm<InstX86Base::Sqrt>(Func, Dest, Src) {} 1333 }; 1334 1335 /// Move/assignment instruction - wrapper for mov/movss/movsd. 1336 class InstX86Mov : public InstX86BaseMovlike<InstX86Base::Mov> { 1337 public: create(Cfg * Func,Variable * Dest,Operand * Source)1338 static InstX86Mov *create(Cfg *Func, Variable *Dest, Operand *Source) { 1339 assert(!isScalarIntegerType(Dest->getType()) || 1340 (typeWidthInBytes(Dest->getType()) <= 1341 typeWidthInBytes(Source->getType()))); 1342 return new (Func->allocate<InstX86Mov>()) InstX86Mov(Func, Dest, Source); 1343 } 1344 1345 void emit(const Cfg *Func) const override; 1346 void emitIAS(const Cfg *Func) const override; 1347 1348 private: InstX86Mov(Cfg * Func,Variable * Dest,Operand * Source)1349 InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source) 1350 : InstX86BaseMovlike<InstX86Base::Mov>(Func, Dest, Source) {} 1351 }; 1352 1353 /// Move packed - copy 128 bit values between XMM registers, or mem128 and XMM 1354 /// registers. 1355 class InstX86Movp : public InstX86BaseMovlike<InstX86Base::Movp> { 1356 public: create(Cfg * Func,Variable * Dest,Operand * Source)1357 static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) { 1358 return new (Func->allocate<InstX86Movp>()) InstX86Movp(Func, Dest, Source); 1359 } 1360 1361 void emit(const Cfg *Func) const override; 1362 void emitIAS(const Cfg *Func) const override; 1363 1364 private: InstX86Movp(Cfg * Func,Variable * Dest,Operand * Source)1365 InstX86Movp(Cfg *Func, Variable *Dest, Operand *Source) 1366 : InstX86BaseMovlike<InstX86Base::Movp>(Func, Dest, Source) {} 1367 }; 1368 1369 /// Movq - copy between XMM registers, or mem64 and XMM registers. 1370 class InstX86Movq : public InstX86BaseMovlike<InstX86Base::Movq> { 1371 public: create(Cfg * Func,Variable * Dest,Operand * Source)1372 static InstX86Movq *create(Cfg *Func, Variable *Dest, Operand *Source) { 1373 return new (Func->allocate<InstX86Movq>()) InstX86Movq(Func, Dest, Source); 1374 } 1375 1376 void emit(const Cfg *Func) const override; 1377 void emitIAS(const Cfg *Func) const override; 1378 1379 private: InstX86Movq(Cfg * Func,Variable * Dest,Operand * Source)1380 InstX86Movq(Cfg *Func, Variable *Dest, Operand *Source) 1381 : InstX86BaseMovlike<InstX86Base::Movq>(Func, Dest, Source) {} 1382 }; 1383 1384 class InstX86Add : public InstX86BaseBinopGPR<InstX86Base::Add> { 1385 public: create(Cfg * Func,Variable * Dest,Operand * Source)1386 static InstX86Add *create(Cfg *Func, Variable *Dest, Operand *Source) { 1387 return new (Func->allocate<InstX86Add>()) InstX86Add(Func, Dest, Source); 1388 } 1389 1390 private: InstX86Add(Cfg * Func,Variable * Dest,Operand * Source)1391 InstX86Add(Cfg *Func, Variable *Dest, Operand *Source) 1392 : InstX86BaseBinopGPR<InstX86Base::Add>(Func, Dest, Source) {} 1393 }; 1394 1395 class InstX86AddRMW : public InstX86BaseBinopRMW<InstX86Base::AddRMW> { 1396 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1397 static InstX86AddRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1398 Operand *Src1) { 1399 return new (Func->allocate<InstX86AddRMW>()) 1400 InstX86AddRMW(Func, DestSrc0, Src1); 1401 } 1402 1403 private: InstX86AddRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1404 InstX86AddRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1405 : InstX86BaseBinopRMW<InstX86Base::AddRMW>(Func, DestSrc0, Src1) {} 1406 }; 1407 1408 class InstX86Addps 1409 : public InstX86BaseBinopXmm<InstX86Base::Addps, true, 1410 InstX86Base::SseSuffix::Packed> { 1411 public: create(Cfg * Func,Variable * Dest,Operand * Source)1412 static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1413 return new (Func->allocate<InstX86Addps>()) 1414 InstX86Addps(Func, Dest, Source); 1415 } 1416 1417 private: InstX86Addps(Cfg * Func,Variable * Dest,Operand * Source)1418 InstX86Addps(Cfg *Func, Variable *Dest, Operand *Source) 1419 : InstX86BaseBinopXmm<InstX86Base::Addps, true, 1420 InstX86Base::SseSuffix::Packed>(Func, Dest, 1421 Source) {} 1422 }; 1423 1424 class InstX86Adc : public InstX86BaseBinopGPR<InstX86Base::Adc> { 1425 public: create(Cfg * Func,Variable * Dest,Operand * Source)1426 static InstX86Adc *create(Cfg *Func, Variable *Dest, Operand *Source) { 1427 return new (Func->allocate<InstX86Adc>()) InstX86Adc(Func, Dest, Source); 1428 } 1429 1430 private: InstX86Adc(Cfg * Func,Variable * Dest,Operand * Source)1431 InstX86Adc(Cfg *Func, Variable *Dest, Operand *Source) 1432 : InstX86BaseBinopGPR<InstX86Base::Adc>(Func, Dest, Source) {} 1433 }; 1434 1435 class InstX86AdcRMW : public InstX86BaseBinopRMW<InstX86Base::AdcRMW> { 1436 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1437 static InstX86AdcRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1438 Operand *Src1) { 1439 return new (Func->allocate<InstX86AdcRMW>()) 1440 InstX86AdcRMW(Func, DestSrc0, Src1); 1441 } 1442 1443 private: InstX86AdcRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1444 InstX86AdcRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1445 : InstX86BaseBinopRMW<InstX86Base::AdcRMW>(Func, DestSrc0, Src1) {} 1446 }; 1447 1448 class InstX86Addss 1449 : public InstX86BaseBinopXmm<InstX86Base::Addss, false, 1450 InstX86Base::SseSuffix::Scalar> { 1451 public: create(Cfg * Func,Variable * Dest,Operand * Source)1452 static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) { 1453 return new (Func->allocate<InstX86Addss>()) 1454 InstX86Addss(Func, Dest, Source); 1455 } 1456 1457 private: InstX86Addss(Cfg * Func,Variable * Dest,Operand * Source)1458 InstX86Addss(Cfg *Func, Variable *Dest, Operand *Source) 1459 : InstX86BaseBinopXmm<InstX86Base::Addss, false, 1460 InstX86Base::SseSuffix::Scalar>(Func, Dest, 1461 Source) {} 1462 }; 1463 1464 class InstX86Padd 1465 : public InstX86BaseBinopXmm<InstX86Base::Padd, true, 1466 InstX86Base::SseSuffix::Integral> { 1467 public: create(Cfg * Func,Variable * Dest,Operand * Source)1468 static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) { 1469 return new (Func->allocate<InstX86Padd>()) InstX86Padd(Func, Dest, Source); 1470 } 1471 1472 private: InstX86Padd(Cfg * Func,Variable * Dest,Operand * Source)1473 InstX86Padd(Cfg *Func, Variable *Dest, Operand *Source) 1474 : InstX86BaseBinopXmm<InstX86Base::Padd, true, 1475 InstX86Base::SseSuffix::Integral>(Func, Dest, 1476 Source) {} 1477 }; 1478 1479 class InstX86Padds 1480 : public InstX86BaseBinopXmm<InstX86Base::Padds, true, 1481 InstX86Base::SseSuffix::Integral> { 1482 public: create(Cfg * Func,Variable * Dest,Operand * Source)1483 static InstX86Padds *create(Cfg *Func, Variable *Dest, Operand *Source) { 1484 return new (Func->allocate<InstX86Padds>()) 1485 InstX86Padds(Func, Dest, Source); 1486 } 1487 1488 private: InstX86Padds(Cfg * Func,Variable * Dest,Operand * Source)1489 InstX86Padds(Cfg *Func, Variable *Dest, Operand *Source) 1490 : InstX86BaseBinopXmm<InstX86Base::Padds, true, 1491 InstX86Base::SseSuffix::Integral>(Func, Dest, 1492 Source) {} 1493 }; 1494 1495 class InstX86Paddus 1496 : public InstX86BaseBinopXmm<InstX86Base::Paddus, true, 1497 InstX86Base::SseSuffix::Integral> { 1498 public: create(Cfg * Func,Variable * Dest,Operand * Source)1499 static InstX86Paddus *create(Cfg *Func, Variable *Dest, Operand *Source) { 1500 return new (Func->allocate<InstX86Paddus>()) 1501 InstX86Paddus(Func, Dest, Source); 1502 } 1503 1504 private: InstX86Paddus(Cfg * Func,Variable * Dest,Operand * Source)1505 InstX86Paddus(Cfg *Func, Variable *Dest, Operand *Source) 1506 : InstX86BaseBinopXmm<InstX86Base::Paddus, true, 1507 InstX86Base::SseSuffix::Integral>(Func, Dest, 1508 Source) {} 1509 }; 1510 1511 class InstX86Sub : public InstX86BaseBinopGPR<InstX86Base::Sub> { 1512 public: create(Cfg * Func,Variable * Dest,Operand * Source)1513 static InstX86Sub *create(Cfg *Func, Variable *Dest, Operand *Source) { 1514 return new (Func->allocate<InstX86Sub>()) InstX86Sub(Func, Dest, Source); 1515 } 1516 1517 private: InstX86Sub(Cfg * Func,Variable * Dest,Operand * Source)1518 InstX86Sub(Cfg *Func, Variable *Dest, Operand *Source) 1519 : InstX86BaseBinopGPR<InstX86Base::Sub>(Func, Dest, Source) {} 1520 }; 1521 1522 class InstX86SubRMW : public InstX86BaseBinopRMW<InstX86Base::SubRMW> { 1523 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1524 static InstX86SubRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1525 Operand *Src1) { 1526 return new (Func->allocate<InstX86SubRMW>()) 1527 InstX86SubRMW(Func, DestSrc0, Src1); 1528 } 1529 1530 private: InstX86SubRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1531 InstX86SubRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1532 : InstX86BaseBinopRMW<InstX86Base::SubRMW>(Func, DestSrc0, Src1) {} 1533 }; 1534 1535 class InstX86Subps 1536 : public InstX86BaseBinopXmm<InstX86Base::Subps, true, 1537 InstX86Base::SseSuffix::Packed> { 1538 public: create(Cfg * Func,Variable * Dest,Operand * Source)1539 static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1540 return new (Func->allocate<InstX86Subps>()) 1541 InstX86Subps(Func, Dest, Source); 1542 } 1543 1544 private: InstX86Subps(Cfg * Func,Variable * Dest,Operand * Source)1545 InstX86Subps(Cfg *Func, Variable *Dest, Operand *Source) 1546 : InstX86BaseBinopXmm<InstX86Base::Subps, true, 1547 InstX86Base::SseSuffix::Packed>(Func, Dest, 1548 Source) {} 1549 }; 1550 1551 class InstX86Subss 1552 : public InstX86BaseBinopXmm<InstX86Base::Subss, false, 1553 InstX86Base::SseSuffix::Scalar> { 1554 public: create(Cfg * Func,Variable * Dest,Operand * Source)1555 static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) { 1556 return new (Func->allocate<InstX86Subss>()) 1557 InstX86Subss(Func, Dest, Source); 1558 } 1559 1560 private: InstX86Subss(Cfg * Func,Variable * Dest,Operand * Source)1561 InstX86Subss(Cfg *Func, Variable *Dest, Operand *Source) 1562 : InstX86BaseBinopXmm<InstX86Base::Subss, false, 1563 InstX86Base::SseSuffix::Scalar>(Func, Dest, 1564 Source) {} 1565 }; 1566 1567 class InstX86Sbb : public InstX86BaseBinopGPR<InstX86Base::Sbb> { 1568 public: create(Cfg * Func,Variable * Dest,Operand * Source)1569 static InstX86Sbb *create(Cfg *Func, Variable *Dest, Operand *Source) { 1570 return new (Func->allocate<InstX86Sbb>()) InstX86Sbb(Func, Dest, Source); 1571 } 1572 1573 private: InstX86Sbb(Cfg * Func,Variable * Dest,Operand * Source)1574 InstX86Sbb(Cfg *Func, Variable *Dest, Operand *Source) 1575 : InstX86BaseBinopGPR<InstX86Base::Sbb>(Func, Dest, Source) {} 1576 }; 1577 1578 class InstX86SbbRMW : public InstX86BaseBinopRMW<InstX86Base::SbbRMW> { 1579 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1580 static InstX86SbbRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1581 Operand *Src1) { 1582 return new (Func->allocate<InstX86SbbRMW>()) 1583 InstX86SbbRMW(Func, DestSrc0, Src1); 1584 } 1585 1586 private: InstX86SbbRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1587 InstX86SbbRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1588 : InstX86BaseBinopRMW<InstX86Base::SbbRMW>(Func, DestSrc0, Src1) {} 1589 }; 1590 1591 class InstX86Psub 1592 : public InstX86BaseBinopXmm<InstX86Base::Psub, true, 1593 InstX86Base::SseSuffix::Integral> { 1594 public: create(Cfg * Func,Variable * Dest,Operand * Source)1595 static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) { 1596 return new (Func->allocate<InstX86Psub>()) InstX86Psub(Func, Dest, Source); 1597 } 1598 1599 private: InstX86Psub(Cfg * Func,Variable * Dest,Operand * Source)1600 InstX86Psub(Cfg *Func, Variable *Dest, Operand *Source) 1601 : InstX86BaseBinopXmm<InstX86Base::Psub, true, 1602 InstX86Base::SseSuffix::Integral>(Func, Dest, 1603 Source) {} 1604 }; 1605 1606 class InstX86Psubs 1607 : public InstX86BaseBinopXmm<InstX86Base::Psubs, true, 1608 InstX86Base::SseSuffix::Integral> { 1609 public: create(Cfg * Func,Variable * Dest,Operand * Source)1610 static InstX86Psubs *create(Cfg *Func, Variable *Dest, Operand *Source) { 1611 return new (Func->allocate<InstX86Psubs>()) 1612 InstX86Psubs(Func, Dest, Source); 1613 } 1614 1615 private: InstX86Psubs(Cfg * Func,Variable * Dest,Operand * Source)1616 InstX86Psubs(Cfg *Func, Variable *Dest, Operand *Source) 1617 : InstX86BaseBinopXmm<InstX86Base::Psubs, true, 1618 InstX86Base::SseSuffix::Integral>(Func, Dest, 1619 Source) {} 1620 }; 1621 1622 class InstX86Psubus 1623 : public InstX86BaseBinopXmm<InstX86Base::Psubus, true, 1624 InstX86Base::SseSuffix::Integral> { 1625 public: create(Cfg * Func,Variable * Dest,Operand * Source)1626 static InstX86Psubus *create(Cfg *Func, Variable *Dest, Operand *Source) { 1627 return new (Func->allocate<InstX86Psubus>()) 1628 InstX86Psubus(Func, Dest, Source); 1629 } 1630 1631 private: InstX86Psubus(Cfg * Func,Variable * Dest,Operand * Source)1632 InstX86Psubus(Cfg *Func, Variable *Dest, Operand *Source) 1633 : InstX86BaseBinopXmm<InstX86Base::Psubus, true, 1634 InstX86Base::SseSuffix::Integral>(Func, Dest, 1635 Source) {} 1636 }; 1637 1638 class InstX86And : public InstX86BaseBinopGPR<InstX86Base::And> { 1639 public: create(Cfg * Func,Variable * Dest,Operand * Source)1640 static InstX86And *create(Cfg *Func, Variable *Dest, Operand *Source) { 1641 return new (Func->allocate<InstX86And>()) InstX86And(Func, Dest, Source); 1642 } 1643 1644 private: InstX86And(Cfg * Func,Variable * Dest,Operand * Source)1645 InstX86And(Cfg *Func, Variable *Dest, Operand *Source) 1646 : InstX86BaseBinopGPR<InstX86Base::And>(Func, Dest, Source) {} 1647 }; 1648 1649 class InstX86Andnps 1650 : public InstX86BaseBinopXmm<InstX86Base::Andnps, true, 1651 InstX86Base::SseSuffix::Packed> { 1652 public: create(Cfg * Func,Variable * Dest,Operand * Source)1653 static InstX86Andnps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1654 return new (Func->allocate<InstX86Andnps>()) 1655 InstX86Andnps(Func, Dest, Source); 1656 } 1657 1658 private: InstX86Andnps(Cfg * Func,Variable * Dest,Operand * Source)1659 InstX86Andnps(Cfg *Func, Variable *Dest, Operand *Source) 1660 : InstX86BaseBinopXmm<InstX86Base::Andnps, true, 1661 InstX86Base::SseSuffix::Packed>(Func, Dest, 1662 Source) {} 1663 }; 1664 1665 class InstX86Andps 1666 : public InstX86BaseBinopXmm<InstX86Base::Andps, true, 1667 InstX86Base::SseSuffix::Packed> { 1668 public: create(Cfg * Func,Variable * Dest,Operand * Source)1669 static InstX86Andps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1670 return new (Func->allocate<InstX86Andps>()) 1671 InstX86Andps(Func, Dest, Source); 1672 } 1673 1674 private: InstX86Andps(Cfg * Func,Variable * Dest,Operand * Source)1675 InstX86Andps(Cfg *Func, Variable *Dest, Operand *Source) 1676 : InstX86BaseBinopXmm<InstX86Base::Andps, true, 1677 InstX86Base::SseSuffix::Packed>(Func, Dest, 1678 Source) {} 1679 }; 1680 1681 class InstX86AndRMW : public InstX86BaseBinopRMW<InstX86Base::AndRMW> { 1682 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1683 static InstX86AndRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1684 Operand *Src1) { 1685 return new (Func->allocate<InstX86AndRMW>()) 1686 InstX86AndRMW(Func, DestSrc0, Src1); 1687 } 1688 1689 private: InstX86AndRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1690 InstX86AndRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1691 : InstX86BaseBinopRMW<InstX86Base::AndRMW>(Func, DestSrc0, Src1) {} 1692 }; 1693 1694 class InstX86Pand : public InstX86BaseBinopXmm<InstX86Base::Pand, false, 1695 InstX86Base::SseSuffix::None> { 1696 public: create(Cfg * Func,Variable * Dest,Operand * Source)1697 static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) { 1698 return new (Func->allocate<InstX86Pand>()) InstX86Pand(Func, Dest, Source); 1699 } 1700 1701 private: InstX86Pand(Cfg * Func,Variable * Dest,Operand * Source)1702 InstX86Pand(Cfg *Func, Variable *Dest, Operand *Source) 1703 : InstX86BaseBinopXmm<InstX86Base::Pand, false, 1704 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1705 }; 1706 1707 class InstX86Pandn : public InstX86BaseBinopXmm<InstX86Base::Pandn, false, 1708 InstX86Base::SseSuffix::None> { 1709 public: create(Cfg * Func,Variable * Dest,Operand * Source)1710 static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) { 1711 return new (Func->allocate<InstX86Pandn>()) 1712 InstX86Pandn(Func, Dest, Source); 1713 } 1714 1715 private: InstX86Pandn(Cfg * Func,Variable * Dest,Operand * Source)1716 InstX86Pandn(Cfg *Func, Variable *Dest, Operand *Source) 1717 : InstX86BaseBinopXmm<InstX86Base::Pandn, false, 1718 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1719 }; 1720 1721 class InstX86Maxss 1722 : public InstX86BaseBinopXmm<InstX86Base::Maxss, true, 1723 InstX86Base::SseSuffix::Scalar> { 1724 public: create(Cfg * Func,Variable * Dest,Operand * Source)1725 static InstX86Maxss *create(Cfg *Func, Variable *Dest, Operand *Source) { 1726 return new (Func->allocate<InstX86Maxss>()) 1727 InstX86Maxss(Func, Dest, Source); 1728 } 1729 1730 private: InstX86Maxss(Cfg * Func,Variable * Dest,Operand * Source)1731 InstX86Maxss(Cfg *Func, Variable *Dest, Operand *Source) 1732 : InstX86BaseBinopXmm<InstX86Base::Maxss, true, 1733 InstX86Base::SseSuffix::Scalar>(Func, Dest, 1734 Source) {} 1735 }; 1736 1737 class InstX86Minss 1738 : public InstX86BaseBinopXmm<InstX86Base::Minss, true, 1739 InstX86Base::SseSuffix::Scalar> { 1740 public: create(Cfg * Func,Variable * Dest,Operand * Source)1741 static InstX86Minss *create(Cfg *Func, Variable *Dest, Operand *Source) { 1742 return new (Func->allocate<InstX86Minss>()) 1743 InstX86Minss(Func, Dest, Source); 1744 } 1745 1746 private: InstX86Minss(Cfg * Func,Variable * Dest,Operand * Source)1747 InstX86Minss(Cfg *Func, Variable *Dest, Operand *Source) 1748 : InstX86BaseBinopXmm<InstX86Base::Minss, true, 1749 InstX86Base::SseSuffix::Scalar>(Func, Dest, 1750 Source) {} 1751 }; 1752 1753 class InstX86Maxps : public InstX86BaseBinopXmm<InstX86Base::Maxps, true, 1754 InstX86Base::SseSuffix::None> { 1755 public: create(Cfg * Func,Variable * Dest,Operand * Source)1756 static InstX86Maxps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1757 return new (Func->allocate<InstX86Maxps>()) 1758 InstX86Maxps(Func, Dest, Source); 1759 } 1760 1761 private: InstX86Maxps(Cfg * Func,Variable * Dest,Operand * Source)1762 InstX86Maxps(Cfg *Func, Variable *Dest, Operand *Source) 1763 : InstX86BaseBinopXmm<InstX86Base::Maxps, true, 1764 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1765 }; 1766 1767 class InstX86Minps : public InstX86BaseBinopXmm<InstX86Base::Minps, true, 1768 InstX86Base::SseSuffix::None> { 1769 public: create(Cfg * Func,Variable * Dest,Operand * Source)1770 static InstX86Minps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1771 return new (Func->allocate<InstX86Minps>()) 1772 InstX86Minps(Func, Dest, Source); 1773 } 1774 1775 private: InstX86Minps(Cfg * Func,Variable * Dest,Operand * Source)1776 InstX86Minps(Cfg *Func, Variable *Dest, Operand *Source) 1777 : InstX86BaseBinopXmm<InstX86Base::Minps, true, 1778 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1779 }; 1780 1781 class InstX86Or : public InstX86BaseBinopGPR<InstX86Base::Or> { 1782 public: create(Cfg * Func,Variable * Dest,Operand * Source)1783 static InstX86Or *create(Cfg *Func, Variable *Dest, Operand *Source) { 1784 return new (Func->allocate<InstX86Or>()) InstX86Or(Func, Dest, Source); 1785 } 1786 1787 private: InstX86Or(Cfg * Func,Variable * Dest,Operand * Source)1788 InstX86Or(Cfg *Func, Variable *Dest, Operand *Source) 1789 : InstX86BaseBinopGPR<InstX86Base::Or>(Func, Dest, Source) {} 1790 }; 1791 1792 class InstX86Orps : public InstX86BaseBinopXmm<InstX86Base::Orps, true, 1793 InstX86Base::SseSuffix::Packed> { 1794 public: create(Cfg * Func,Variable * Dest,Operand * Source)1795 static InstX86Orps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1796 return new (Func->allocate<InstX86Orps>()) InstX86Orps(Func, Dest, Source); 1797 } 1798 1799 private: InstX86Orps(Cfg * Func,Variable * Dest,Operand * Source)1800 InstX86Orps(Cfg *Func, Variable *Dest, Operand *Source) 1801 : InstX86BaseBinopXmm<InstX86Base::Orps, true, 1802 InstX86Base::SseSuffix::Packed>(Func, Dest, 1803 Source) {} 1804 }; 1805 1806 class InstX86OrRMW : public InstX86BaseBinopRMW<InstX86Base::OrRMW> { 1807 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1808 static InstX86OrRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1809 Operand *Src1) { 1810 return new (Func->allocate<InstX86OrRMW>()) 1811 InstX86OrRMW(Func, DestSrc0, Src1); 1812 } 1813 1814 private: InstX86OrRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1815 InstX86OrRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1816 : InstX86BaseBinopRMW<InstX86Base::OrRMW>(Func, DestSrc0, Src1) {} 1817 }; 1818 1819 class InstX86Por : public InstX86BaseBinopXmm<InstX86Base::Por, false, 1820 InstX86Base::SseSuffix::None> { 1821 public: create(Cfg * Func,Variable * Dest,Operand * Source)1822 static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) { 1823 return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source); 1824 } 1825 1826 private: InstX86Por(Cfg * Func,Variable * Dest,Operand * Source)1827 InstX86Por(Cfg *Func, Variable *Dest, Operand *Source) 1828 : InstX86BaseBinopXmm<InstX86Base::Por, false, 1829 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1830 }; 1831 1832 class InstX86Xor : public InstX86BaseBinopGPR<InstX86Base::Xor> { 1833 public: create(Cfg * Func,Variable * Dest,Operand * Source)1834 static InstX86Xor *create(Cfg *Func, Variable *Dest, Operand *Source) { 1835 return new (Func->allocate<InstX86Xor>()) InstX86Xor(Func, Dest, Source); 1836 } 1837 1838 private: InstX86Xor(Cfg * Func,Variable * Dest,Operand * Source)1839 InstX86Xor(Cfg *Func, Variable *Dest, Operand *Source) 1840 : InstX86BaseBinopGPR<InstX86Base::Xor>(Func, Dest, Source) {} 1841 }; 1842 1843 class InstX86Xorps 1844 : public InstX86BaseBinopXmm<InstX86Base::Xorps, true, 1845 InstX86Base::SseSuffix::Packed> { 1846 public: create(Cfg * Func,Variable * Dest,Operand * Source)1847 static InstX86Xorps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1848 return new (Func->allocate<InstX86Xorps>()) 1849 InstX86Xorps(Func, Dest, Source); 1850 } 1851 1852 private: InstX86Xorps(Cfg * Func,Variable * Dest,Operand * Source)1853 InstX86Xorps(Cfg *Func, Variable *Dest, Operand *Source) 1854 : InstX86BaseBinopXmm<InstX86Base::Xorps, true, 1855 InstX86Base::SseSuffix::Packed>(Func, Dest, 1856 Source) {} 1857 }; 1858 1859 class InstX86XorRMW : public InstX86BaseBinopRMW<InstX86Base::XorRMW> { 1860 public: create(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1861 static InstX86XorRMW *create(Cfg *Func, X86OperandMem *DestSrc0, 1862 Operand *Src1) { 1863 return new (Func->allocate<InstX86XorRMW>()) 1864 InstX86XorRMW(Func, DestSrc0, Src1); 1865 } 1866 1867 private: InstX86XorRMW(Cfg * Func,X86OperandMem * DestSrc0,Operand * Src1)1868 InstX86XorRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 1869 : InstX86BaseBinopRMW<InstX86Base::XorRMW>(Func, DestSrc0, Src1) {} 1870 }; 1871 1872 class InstX86Pxor : public InstX86BaseBinopXmm<InstX86Base::Pxor, false, 1873 InstX86Base::SseSuffix::None> { 1874 public: create(Cfg * Func,Variable * Dest,Operand * Source)1875 static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) { 1876 return new (Func->allocate<InstX86Pxor>()) InstX86Pxor(Func, Dest, Source); 1877 } 1878 1879 private: InstX86Pxor(Cfg * Func,Variable * Dest,Operand * Source)1880 InstX86Pxor(Cfg *Func, Variable *Dest, Operand *Source) 1881 : InstX86BaseBinopXmm<InstX86Base::Pxor, false, 1882 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1883 }; 1884 1885 class InstX86Imul : public InstX86BaseBinopGPR<InstX86Base::Imul> { 1886 public: create(Cfg * Func,Variable * Dest,Operand * Source)1887 static InstX86Imul *create(Cfg *Func, Variable *Dest, Operand *Source) { 1888 return new (Func->allocate<InstX86Imul>()) InstX86Imul(Func, Dest, Source); 1889 } 1890 1891 void emit(const Cfg *Func) const override; 1892 void emitIAS(const Cfg *Func) const override; 1893 1894 private: InstX86Imul(Cfg * Func,Variable * Dest,Operand * Source)1895 InstX86Imul(Cfg *Func, Variable *Dest, Operand *Source) 1896 : InstX86BaseBinopGPR<InstX86Base::Imul>(Func, Dest, Source) {} 1897 }; 1898 1899 class InstX86ImulImm : public InstX86BaseThreeAddressop<InstX86Base::ImulImm> { 1900 public: create(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)1901 static InstX86ImulImm *create(Cfg *Func, Variable *Dest, Operand *Source0, 1902 Operand *Source1) { 1903 return new (Func->allocate<InstX86ImulImm>()) 1904 InstX86ImulImm(Func, Dest, Source0, Source1); 1905 } 1906 1907 void emit(const Cfg *Func) const override; 1908 void emitIAS(const Cfg *Func) const override; 1909 1910 private: InstX86ImulImm(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)1911 InstX86ImulImm(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1) 1912 : InstX86BaseThreeAddressop<InstX86Base::ImulImm>(Func, Dest, Source0, 1913 Source1) {} 1914 }; 1915 1916 class InstX86Mulps 1917 : public InstX86BaseBinopXmm<InstX86Base::Mulps, true, 1918 InstX86Base::SseSuffix::Packed> { 1919 public: create(Cfg * Func,Variable * Dest,Operand * Source)1920 static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) { 1921 return new (Func->allocate<InstX86Mulps>()) 1922 InstX86Mulps(Func, Dest, Source); 1923 } 1924 1925 private: InstX86Mulps(Cfg * Func,Variable * Dest,Operand * Source)1926 InstX86Mulps(Cfg *Func, Variable *Dest, Operand *Source) 1927 : InstX86BaseBinopXmm<InstX86Base::Mulps, true, 1928 InstX86Base::SseSuffix::Packed>(Func, Dest, 1929 Source) {} 1930 }; 1931 1932 class InstX86Mulss 1933 : public InstX86BaseBinopXmm<InstX86Base::Mulss, false, 1934 InstX86Base::SseSuffix::Scalar> { 1935 public: create(Cfg * Func,Variable * Dest,Operand * Source)1936 static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) { 1937 return new (Func->allocate<InstX86Mulss>()) 1938 InstX86Mulss(Func, Dest, Source); 1939 } 1940 1941 private: InstX86Mulss(Cfg * Func,Variable * Dest,Operand * Source)1942 InstX86Mulss(Cfg *Func, Variable *Dest, Operand *Source) 1943 : InstX86BaseBinopXmm<InstX86Base::Mulss, false, 1944 InstX86Base::SseSuffix::Scalar>(Func, Dest, 1945 Source) {} 1946 }; 1947 1948 class InstX86Pmull 1949 : public InstX86BaseBinopXmm<InstX86Base::Pmull, true, 1950 InstX86Base::SseSuffix::Integral> { 1951 public: create(Cfg * Func,Variable * Dest,Operand * Source)1952 static InstX86Pmull *create(Cfg *Func, Variable *Dest, Operand *Source) { 1953 bool TypesAreValid = 1954 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16; 1955 bool InstructionSetIsValid = 1956 Dest->getType() == IceType_v8i16 || getInstructionSet(Func) >= SSE4_1; 1957 (void)TypesAreValid; 1958 (void)InstructionSetIsValid; 1959 assert(TypesAreValid); 1960 assert(InstructionSetIsValid); 1961 return new (Func->allocate<InstX86Pmull>()) 1962 InstX86Pmull(Func, Dest, Source); 1963 } 1964 1965 private: InstX86Pmull(Cfg * Func,Variable * Dest,Operand * Source)1966 InstX86Pmull(Cfg *Func, Variable *Dest, Operand *Source) 1967 : InstX86BaseBinopXmm<InstX86Base::Pmull, true, 1968 InstX86Base::SseSuffix::Integral>(Func, Dest, 1969 Source) {} 1970 }; 1971 1972 class InstX86Pmulhw : public InstX86BaseBinopXmm<InstX86Base::Pmulhw, false, 1973 InstX86Base::SseSuffix::None> { 1974 public: create(Cfg * Func,Variable * Dest,Operand * Source)1975 static InstX86Pmulhw *create(Cfg *Func, Variable *Dest, Operand *Source) { 1976 assert(Dest->getType() == IceType_v8i16 && 1977 Source->getType() == IceType_v8i16); 1978 return new (Func->allocate<InstX86Pmulhw>()) 1979 InstX86Pmulhw(Func, Dest, Source); 1980 } 1981 1982 private: InstX86Pmulhw(Cfg * Func,Variable * Dest,Operand * Source)1983 InstX86Pmulhw(Cfg *Func, Variable *Dest, Operand *Source) 1984 : InstX86BaseBinopXmm<InstX86Base::Pmulhw, false, 1985 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 1986 }; 1987 1988 class InstX86Pmulhuw 1989 : public InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false, 1990 InstX86Base::SseSuffix::None> { 1991 public: create(Cfg * Func,Variable * Dest,Operand * Source)1992 static InstX86Pmulhuw *create(Cfg *Func, Variable *Dest, Operand *Source) { 1993 assert(Dest->getType() == IceType_v8i16 && 1994 Source->getType() == IceType_v8i16); 1995 return new (Func->allocate<InstX86Pmulhuw>()) 1996 InstX86Pmulhuw(Func, Dest, Source); 1997 } 1998 1999 private: InstX86Pmulhuw(Cfg * Func,Variable * Dest,Operand * Source)2000 InstX86Pmulhuw(Cfg *Func, Variable *Dest, Operand *Source) 2001 : InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false, 2002 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 2003 }; 2004 2005 class InstX86Pmaddwd 2006 : public InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false, 2007 InstX86Base::SseSuffix::None> { 2008 public: create(Cfg * Func,Variable * Dest,Operand * Source)2009 static InstX86Pmaddwd *create(Cfg *Func, Variable *Dest, Operand *Source) { 2010 assert(Dest->getType() == IceType_v8i16 && 2011 Source->getType() == IceType_v8i16); 2012 return new (Func->allocate<InstX86Pmaddwd>()) 2013 InstX86Pmaddwd(Func, Dest, Source); 2014 } 2015 2016 private: InstX86Pmaddwd(Cfg * Func,Variable * Dest,Operand * Source)2017 InstX86Pmaddwd(Cfg *Func, Variable *Dest, Operand *Source) 2018 : InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false, 2019 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 2020 }; 2021 2022 class InstX86Pmuludq 2023 : public InstX86BaseBinopXmm<InstX86Base::Pmuludq, false, 2024 InstX86Base::SseSuffix::None> { 2025 public: create(Cfg * Func,Variable * Dest,Operand * Source)2026 static InstX86Pmuludq *create(Cfg *Func, Variable *Dest, Operand *Source) { 2027 assert(Dest->getType() == IceType_v4i32 && 2028 Source->getType() == IceType_v4i32); 2029 return new (Func->allocate<InstX86Pmuludq>()) 2030 InstX86Pmuludq(Func, Dest, Source); 2031 } 2032 2033 private: InstX86Pmuludq(Cfg * Func,Variable * Dest,Operand * Source)2034 InstX86Pmuludq(Cfg *Func, Variable *Dest, Operand *Source) 2035 : InstX86BaseBinopXmm<InstX86Base::Pmuludq, false, 2036 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 2037 }; 2038 2039 class InstX86Divps 2040 : public InstX86BaseBinopXmm<InstX86Base::Divps, true, 2041 InstX86Base::SseSuffix::Packed> { 2042 public: create(Cfg * Func,Variable * Dest,Operand * Source)2043 static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) { 2044 return new (Func->allocate<InstX86Divps>()) 2045 InstX86Divps(Func, Dest, Source); 2046 } 2047 2048 private: InstX86Divps(Cfg * Func,Variable * Dest,Operand * Source)2049 InstX86Divps(Cfg *Func, Variable *Dest, Operand *Source) 2050 : InstX86BaseBinopXmm<InstX86Base::Divps, true, 2051 InstX86Base::SseSuffix::Packed>(Func, Dest, 2052 Source) {} 2053 }; 2054 2055 class InstX86Divss 2056 : public InstX86BaseBinopXmm<InstX86Base::Divss, false, 2057 InstX86Base::SseSuffix::Scalar> { 2058 public: create(Cfg * Func,Variable * Dest,Operand * Source)2059 static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) { 2060 return new (Func->allocate<InstX86Divss>()) 2061 InstX86Divss(Func, Dest, Source); 2062 } 2063 2064 private: InstX86Divss(Cfg * Func,Variable * Dest,Operand * Source)2065 InstX86Divss(Cfg *Func, Variable *Dest, Operand *Source) 2066 : InstX86BaseBinopXmm<InstX86Base::Divss, false, 2067 InstX86Base::SseSuffix::Scalar>(Func, Dest, 2068 Source) {} 2069 }; 2070 2071 class InstX86Rol : public InstX86BaseBinopGPRShift<InstX86Base::Rol> { 2072 public: create(Cfg * Func,Variable * Dest,Operand * Source)2073 static InstX86Rol *create(Cfg *Func, Variable *Dest, Operand *Source) { 2074 return new (Func->allocate<InstX86Rol>()) InstX86Rol(Func, Dest, Source); 2075 } 2076 2077 private: InstX86Rol(Cfg * Func,Variable * Dest,Operand * Source)2078 InstX86Rol(Cfg *Func, Variable *Dest, Operand *Source) 2079 : InstX86BaseBinopGPRShift<InstX86Base::Rol>(Func, Dest, Source) {} 2080 }; 2081 2082 class InstX86Shl : public InstX86BaseBinopGPRShift<InstX86Base::Shl> { 2083 public: create(Cfg * Func,Variable * Dest,Operand * Source)2084 static InstX86Shl *create(Cfg *Func, Variable *Dest, Operand *Source) { 2085 return new (Func->allocate<InstX86Shl>()) InstX86Shl(Func, Dest, Source); 2086 } 2087 2088 private: InstX86Shl(Cfg * Func,Variable * Dest,Operand * Source)2089 InstX86Shl(Cfg *Func, Variable *Dest, Operand *Source) 2090 : InstX86BaseBinopGPRShift<InstX86Base::Shl>(Func, Dest, Source) {} 2091 }; 2092 2093 class InstX86Psll : public InstX86BaseBinopXmmShift<InstX86Base::Psll> { 2094 public: create(Cfg * Func,Variable * Dest,Operand * Source)2095 static InstX86Psll *create(Cfg *Func, Variable *Dest, Operand *Source) { 2096 assert(Dest->getType() == IceType_v8i16 || 2097 Dest->getType() == IceType_v8i1 || 2098 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1); 2099 return new (Func->allocate<InstX86Psll>()) InstX86Psll(Func, Dest, Source); 2100 } 2101 2102 private: InstX86Psll(Cfg * Func,Variable * Dest,Operand * Source)2103 InstX86Psll(Cfg *Func, Variable *Dest, Operand *Source) 2104 : InstX86BaseBinopXmmShift<InstX86Base::Psll>(Func, Dest, Source) {} 2105 }; 2106 2107 class InstX86Psrl : public InstX86BaseBinopXmmShift<InstX86Base::Psrl, true> { 2108 public: create(Cfg * Func,Variable * Dest,Operand * Source)2109 static InstX86Psrl *create(Cfg *Func, Variable *Dest, Operand *Source) { 2110 return new (Func->allocate<InstX86Psrl>()) InstX86Psrl(Func, Dest, Source); 2111 } 2112 2113 private: InstX86Psrl(Cfg * Func,Variable * Dest,Operand * Source)2114 InstX86Psrl(Cfg *Func, Variable *Dest, Operand *Source) 2115 : InstX86BaseBinopXmmShift<InstX86Base::Psrl, true>(Func, Dest, Source) {} 2116 }; 2117 2118 class InstX86Shr : public InstX86BaseBinopGPRShift<InstX86Base::Shr> { 2119 public: create(Cfg * Func,Variable * Dest,Operand * Source)2120 static InstX86Shr *create(Cfg *Func, Variable *Dest, Operand *Source) { 2121 return new (Func->allocate<InstX86Shr>()) InstX86Shr(Func, Dest, Source); 2122 } 2123 2124 private: InstX86Shr(Cfg * Func,Variable * Dest,Operand * Source)2125 InstX86Shr(Cfg *Func, Variable *Dest, Operand *Source) 2126 : InstX86BaseBinopGPRShift<InstX86Base::Shr>(Func, Dest, Source) {} 2127 }; 2128 2129 class InstX86Sar : public InstX86BaseBinopGPRShift<InstX86Base::Sar> { 2130 public: create(Cfg * Func,Variable * Dest,Operand * Source)2131 static InstX86Sar *create(Cfg *Func, Variable *Dest, Operand *Source) { 2132 return new (Func->allocate<InstX86Sar>()) InstX86Sar(Func, Dest, Source); 2133 } 2134 2135 private: InstX86Sar(Cfg * Func,Variable * Dest,Operand * Source)2136 InstX86Sar(Cfg *Func, Variable *Dest, Operand *Source) 2137 : InstX86BaseBinopGPRShift<InstX86Base::Sar>(Func, Dest, Source) {} 2138 }; 2139 2140 class InstX86Psra : public InstX86BaseBinopXmmShift<InstX86Base::Psra> { 2141 public: create(Cfg * Func,Variable * Dest,Operand * Source)2142 static InstX86Psra *create(Cfg *Func, Variable *Dest, Operand *Source) { 2143 assert(Dest->getType() == IceType_v8i16 || 2144 Dest->getType() == IceType_v8i1 || 2145 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1); 2146 return new (Func->allocate<InstX86Psra>()) InstX86Psra(Func, Dest, Source); 2147 } 2148 2149 private: InstX86Psra(Cfg * Func,Variable * Dest,Operand * Source)2150 InstX86Psra(Cfg *Func, Variable *Dest, Operand *Source) 2151 : InstX86BaseBinopXmmShift<InstX86Base::Psra>(Func, Dest, Source) {} 2152 }; 2153 2154 class InstX86Pcmpeq 2155 : public InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true, 2156 InstX86Base::SseSuffix::Integral> { 2157 public: 2158 static InstX86Pcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source, 2159 Type ArithmeticTypeOverride = IceType_void) { 2160 const Type Ty = ArithmeticTypeOverride == IceType_void 2161 ? Dest->getType() 2162 : ArithmeticTypeOverride; 2163 (void)Ty; 2164 assert((Ty != IceType_f64 && Ty != IceType_i64) || 2165 getInstructionSet(Func) >= SSE4_1); 2166 return new (Func->allocate<InstX86Pcmpeq>()) 2167 InstX86Pcmpeq(Func, Dest, Source, ArithmeticTypeOverride); 2168 } 2169 2170 private: InstX86Pcmpeq(Cfg * Func,Variable * Dest,Operand * Source,Type ArithmeticTypeOverride)2171 InstX86Pcmpeq(Cfg *Func, Variable *Dest, Operand *Source, 2172 Type ArithmeticTypeOverride) 2173 : InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true, 2174 InstX86Base::SseSuffix::Integral>( 2175 Func, Dest, Source, ArithmeticTypeOverride) {} 2176 }; 2177 2178 class InstX86Pcmpgt 2179 : public InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true, 2180 InstX86Base::SseSuffix::Integral> { 2181 public: create(Cfg * Func,Variable * Dest,Operand * Source)2182 static InstX86Pcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) { 2183 assert(Dest->getType() != IceType_f64 || getInstructionSet(Func) >= SSE4_1); 2184 return new (Func->allocate<InstX86Pcmpgt>()) 2185 InstX86Pcmpgt(Func, Dest, Source); 2186 } 2187 2188 private: InstX86Pcmpgt(Cfg * Func,Variable * Dest,Operand * Source)2189 InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source) 2190 : InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true, 2191 InstX86Base::SseSuffix::Integral>(Func, Dest, 2192 Source) {} 2193 }; 2194 2195 /// movss is only a binary operation when the source and dest operands are 2196 /// both registers (the high bits of dest are left untouched). In other cases, 2197 /// it behaves like a copy (mov-like) operation (and the high bits of dest are 2198 /// cleared). InstX86Movss will assert that both its source and dest operands 2199 /// are registers, so the lowering code should use _mov instead of _movss in 2200 /// cases where a copy operation is intended. 2201 class InstX86MovssRegs 2202 : public InstX86BaseBinopXmm<InstX86Base::MovssRegs, false, 2203 InstX86Base::SseSuffix::None> { 2204 public: create(Cfg * Func,Variable * Dest,Operand * Source)2205 static InstX86MovssRegs *create(Cfg *Func, Variable *Dest, Operand *Source) { 2206 return new (Func->allocate<InstX86MovssRegs>()) 2207 InstX86MovssRegs(Func, Dest, Source); 2208 } 2209 2210 void emitIAS(const Cfg *Func) const override; 2211 2212 private: InstX86MovssRegs(Cfg * Func,Variable * Dest,Operand * Source)2213 InstX86MovssRegs(Cfg *Func, Variable *Dest, Operand *Source) 2214 : InstX86BaseBinopXmm<InstX86Base::MovssRegs, false, 2215 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 2216 }; 2217 2218 class InstX86Idiv : public InstX86BaseTernop<InstX86Base::Idiv> { 2219 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2220 static InstX86Idiv *create(Cfg *Func, Variable *Dest, Operand *Source1, 2221 Operand *Source2) { 2222 return new (Func->allocate<InstX86Idiv>()) 2223 InstX86Idiv(Func, Dest, Source1, Source2); 2224 } 2225 2226 void emit(const Cfg *Func) const override; 2227 void emitIAS(const Cfg *Func) const override; 2228 2229 private: InstX86Idiv(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2230 InstX86Idiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2231 : InstX86BaseTernop<InstX86Base::Idiv>(Func, Dest, Source1, Source2) {} 2232 }; 2233 2234 class InstX86Div : public InstX86BaseTernop<InstX86Base::Div> { 2235 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2236 static InstX86Div *create(Cfg *Func, Variable *Dest, Operand *Source1, 2237 Operand *Source2) { 2238 return new (Func->allocate<InstX86Div>()) 2239 InstX86Div(Func, Dest, Source1, Source2); 2240 } 2241 2242 void emit(const Cfg *Func) const override; 2243 void emitIAS(const Cfg *Func) const override; 2244 2245 private: InstX86Div(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2246 InstX86Div(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2247 : InstX86BaseTernop<InstX86Base::Div>(Func, Dest, Source1, Source2) {} 2248 }; 2249 2250 class InstX86Insertps : public InstX86BaseTernop<InstX86Base::Insertps> { 2251 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2252 static InstX86Insertps *create(Cfg *Func, Variable *Dest, Operand *Source1, 2253 Operand *Source2) { 2254 return new (Func->allocate<InstX86Insertps>()) 2255 InstX86Insertps(Func, Dest, Source1, Source2); 2256 } 2257 2258 void emitIAS(const Cfg *Func) const override; 2259 2260 private: InstX86Insertps(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2261 InstX86Insertps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2262 : InstX86BaseTernop<InstX86Base::Insertps>(Func, Dest, Source1, Source2) { 2263 } 2264 }; 2265 2266 class InstX86Pinsr : public InstX86BaseTernop<InstX86Base::Pinsr> { 2267 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2268 static InstX86Pinsr *create(Cfg *Func, Variable *Dest, Operand *Source1, 2269 Operand *Source2) { 2270 // pinsrb and pinsrd are SSE4.1 instructions. 2271 assert(Dest->getType() == IceType_v8i16 || 2272 Dest->getType() == IceType_v8i1 || 2273 getInstructionSet(Func) >= SSE4_1); 2274 return new (Func->allocate<InstX86Pinsr>()) 2275 InstX86Pinsr(Func, Dest, Source1, Source2); 2276 } 2277 2278 void emit(const Cfg *Func) const override; 2279 void emitIAS(const Cfg *Func) const override; 2280 2281 private: InstX86Pinsr(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2282 InstX86Pinsr(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2283 : InstX86BaseTernop<InstX86Base::Pinsr>(Func, Dest, Source1, Source2) {} 2284 }; 2285 2286 class InstX86Shufps : public InstX86BaseTernop<InstX86Base::Shufps> { 2287 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2288 static InstX86Shufps *create(Cfg *Func, Variable *Dest, Operand *Source1, 2289 Operand *Source2) { 2290 return new (Func->allocate<InstX86Shufps>()) 2291 InstX86Shufps(Func, Dest, Source1, Source2); 2292 } 2293 2294 void emitIAS(const Cfg *Func) const override; 2295 2296 private: InstX86Shufps(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2297 InstX86Shufps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2298 : InstX86BaseTernop<InstX86Base::Shufps>(Func, Dest, Source1, Source2) {} 2299 }; 2300 2301 class InstX86Blendvps : public InstX86BaseTernop<InstX86Base::Blendvps> { 2302 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2303 static InstX86Blendvps *create(Cfg *Func, Variable *Dest, Operand *Source1, 2304 Operand *Source2) { 2305 assert(getInstructionSet(Func) >= SSE4_1); 2306 return new (Func->allocate<InstX86Blendvps>()) 2307 InstX86Blendvps(Func, Dest, Source1, Source2); 2308 } 2309 2310 void emit(const Cfg *Func) const override; 2311 void emitIAS(const Cfg *Fund) const override; 2312 2313 private: InstX86Blendvps(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2314 InstX86Blendvps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2315 : InstX86BaseTernop<InstX86Base::Blendvps>(Func, Dest, Source1, Source2) { 2316 } 2317 }; 2318 2319 class InstX86Pblendvb : public InstX86BaseTernop<InstX86Base::Pblendvb> { 2320 public: create(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2321 static InstX86Pblendvb *create(Cfg *Func, Variable *Dest, Operand *Source1, 2322 Operand *Source2) { 2323 assert(getInstructionSet(Func) >= SSE4_1); 2324 return new (Func->allocate<InstX86Pblendvb>()) 2325 InstX86Pblendvb(Func, Dest, Source1, Source2); 2326 } 2327 2328 void emit(const Cfg *Func) const override; 2329 void emitIAS(const Cfg *Func) const override; 2330 2331 private: InstX86Pblendvb(Cfg * Func,Variable * Dest,Operand * Source1,Operand * Source2)2332 InstX86Pblendvb(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 2333 : InstX86BaseTernop<InstX86Base::Pblendvb>(Func, Dest, Source1, Source2) { 2334 } 2335 }; 2336 2337 class InstX86Pextr : public InstX86BaseThreeAddressop<InstX86Base::Pextr> { 2338 public: create(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)2339 static InstX86Pextr *create(Cfg *Func, Variable *Dest, Operand *Source0, 2340 Operand *Source1) { 2341 assert(Source0->getType() == IceType_v8i16 || 2342 Source0->getType() == IceType_v8i1 || 2343 getInstructionSet(Func) >= SSE4_1); 2344 return new (Func->allocate<InstX86Pextr>()) 2345 InstX86Pextr(Func, Dest, Source0, Source1); 2346 } 2347 2348 void emit(const Cfg *Func) const override; 2349 void emitIAS(const Cfg *Func) const override; 2350 2351 private: InstX86Pextr(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)2352 InstX86Pextr(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1) 2353 : InstX86BaseThreeAddressop<InstX86Base::Pextr>(Func, Dest, Source0, 2354 Source1) {} 2355 }; 2356 2357 class InstX86Pshufd : public InstX86BaseThreeAddressop<InstX86Base::Pshufd> { 2358 public: create(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)2359 static InstX86Pshufd *create(Cfg *Func, Variable *Dest, Operand *Source0, 2360 Operand *Source1) { 2361 return new (Func->allocate<InstX86Pshufd>()) 2362 InstX86Pshufd(Func, Dest, Source0, Source1); 2363 } 2364 2365 void emitIAS(const Cfg *Func) const override; 2366 2367 private: InstX86Pshufd(Cfg * Func,Variable * Dest,Operand * Source0,Operand * Source1)2368 InstX86Pshufd(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1) 2369 : InstX86BaseThreeAddressop<InstX86Base::Pshufd>(Func, Dest, Source0, 2370 Source1) {} 2371 }; 2372 2373 /// Base class for a lockable x86-32 instruction (emits a locked prefix). 2374 class InstX86BaseLockable : public InstX86Base { 2375 InstX86BaseLockable() = delete; 2376 InstX86BaseLockable(const InstX86BaseLockable &) = delete; 2377 InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete; 2378 2379 protected: 2380 bool Locked; 2381 InstX86BaseLockable(Cfg * Func,typename InstX86Base::InstKindX86 Kind,SizeT Maxsrcs,Variable * Dest,bool Locked)2382 InstX86BaseLockable(Cfg *Func, typename InstX86Base::InstKindX86 Kind, 2383 SizeT Maxsrcs, Variable *Dest, bool Locked) 2384 : InstX86Base(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 2385 // Assume that such instructions are used for Atomics and be careful with 2386 // optimizations. 2387 this->HasSideEffects = Locked; 2388 } 2389 }; 2390 2391 /// Mul instruction - unsigned multiply. 2392 class InstX86Mul final : public InstX86Base { 2393 InstX86Mul() = delete; 2394 InstX86Mul(const InstX86Mul &) = delete; 2395 InstX86Mul &operator=(const InstX86Mul &) = delete; 2396 2397 public: create(Cfg * Func,Variable * Dest,Variable * Source1,Operand * Source2)2398 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 2399 Operand *Source2) { 2400 return new (Func->allocate<InstX86Mul>()) 2401 InstX86Mul(Func, Dest, Source1, Source2); 2402 } 2403 void emit(const Cfg *Func) const override; 2404 void emitIAS(const Cfg *Func) const override; 2405 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2406 static bool classof(const Inst *Instr) { 2407 return InstX86Base::isClassof(Instr, InstX86Base::Mul); 2408 } 2409 2410 private: 2411 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2412 }; 2413 2414 /// Shld instruction - shift across a pair of operands. 2415 class InstX86Shld final : public InstX86Base { 2416 InstX86Shld() = delete; 2417 InstX86Shld(const InstX86Shld &) = delete; 2418 InstX86Shld &operator=(const InstX86Shld &) = delete; 2419 2420 public: create(Cfg * Func,Variable * Dest,Variable * Source1,Operand * Source2)2421 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 2422 Operand *Source2) { 2423 return new (Func->allocate<InstX86Shld>()) 2424 InstX86Shld(Func, Dest, Source1, Source2); 2425 } 2426 void emit(const Cfg *Func) const override; 2427 void emitIAS(const Cfg *Func) const override; 2428 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2429 static bool classof(const Inst *Instr) { 2430 return InstX86Base::isClassof(Instr, InstX86Base::Shld); 2431 } 2432 2433 private: 2434 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2435 }; 2436 2437 /// Shrd instruction - shift across a pair of operands. 2438 class InstX86Shrd final : public InstX86Base { 2439 InstX86Shrd() = delete; 2440 InstX86Shrd(const InstX86Shrd &) = delete; 2441 InstX86Shrd &operator=(const InstX86Shrd &) = delete; 2442 2443 public: create(Cfg * Func,Variable * Dest,Variable * Source1,Operand * Source2)2444 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 2445 Operand *Source2) { 2446 return new (Func->allocate<InstX86Shrd>()) 2447 InstX86Shrd(Func, Dest, Source1, Source2); 2448 } 2449 void emit(const Cfg *Func) const override; 2450 void emitIAS(const Cfg *Func) const override; 2451 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2452 static bool classof(const Inst *Instr) { 2453 return InstX86Base::isClassof(Instr, InstX86Base::Shrd); 2454 } 2455 2456 private: 2457 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2458 }; 2459 2460 /// Conditional move instruction. 2461 class InstX86Cmov final : public InstX86Base { 2462 InstX86Cmov() = delete; 2463 InstX86Cmov(const InstX86Cmov &) = delete; 2464 InstX86Cmov &operator=(const InstX86Cmov &) = delete; 2465 2466 public: create(Cfg * Func,Variable * Dest,Operand * Source,BrCond Cond)2467 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 2468 BrCond Cond) { 2469 return new (Func->allocate<InstX86Cmov>()) 2470 InstX86Cmov(Func, Dest, Source, Cond); 2471 } 2472 void emit(const Cfg *Func) const override; 2473 void emitIAS(const Cfg *Func) const override; 2474 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2475 static bool classof(const Inst *Instr) { 2476 return InstX86Base::isClassof(Instr, InstX86Base::Cmov); 2477 } 2478 2479 private: 2480 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond); 2481 2482 BrCond Condition; 2483 }; 2484 2485 /// Cmpps instruction - compare packed singled-precision floating point values 2486 class InstX86Cmpps final : public InstX86Base { 2487 InstX86Cmpps() = delete; 2488 InstX86Cmpps(const InstX86Cmpps &) = delete; 2489 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete; 2490 2491 public: create(Cfg * Func,Variable * Dest,Operand * Source,CmppsCond Condition)2492 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 2493 CmppsCond Condition) { 2494 return new (Func->allocate<InstX86Cmpps>()) 2495 InstX86Cmpps(Func, Dest, Source, Condition); 2496 } 2497 void emit(const Cfg *Func) const override; 2498 void emitIAS(const Cfg *Func) const override; 2499 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2500 static bool classof(const Inst *Instr) { 2501 return InstX86Base::isClassof(Instr, InstX86Base::Cmpps); 2502 } 2503 2504 private: 2505 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond); 2506 2507 CmppsCond Condition; 2508 }; 2509 2510 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 2511 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If 2512 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest> 2513 /// can be a register or memory, while <desired> must be a register. It is 2514 /// the user's responsibility to mark eax with a FakeDef. 2515 class InstX86Cmpxchg final : public InstX86BaseLockable { 2516 InstX86Cmpxchg() = delete; 2517 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete; 2518 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete; 2519 2520 public: create(Cfg * Func,Operand * DestOrAddr,Variable * Eax,Variable * Desired,bool Locked)2521 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2522 Variable *Desired, bool Locked) { 2523 return new (Func->allocate<InstX86Cmpxchg>()) 2524 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 2525 } 2526 void emit(const Cfg *Func) const override; 2527 void emitIAS(const Cfg *Func) const override; 2528 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2529 static bool classof(const Inst *Instr) { 2530 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg); 2531 } 2532 2533 private: 2534 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2535 Variable *Desired, bool Locked); 2536 }; 2537 2538 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals 2539 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF 2540 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for 2541 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory 2542 /// operand. 2543 class InstX86Cmpxchg8b final : public InstX86BaseLockable { 2544 InstX86Cmpxchg8b() = delete; 2545 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete; 2546 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete; 2547 2548 public: create(Cfg * Func,X86OperandMem * Dest,Variable * Edx,Variable * Eax,Variable * Ecx,Variable * Ebx,bool Locked)2549 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest, Variable *Edx, 2550 Variable *Eax, Variable *Ecx, Variable *Ebx, 2551 bool Locked) { 2552 return new (Func->allocate<InstX86Cmpxchg8b>()) 2553 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 2554 } 2555 void emit(const Cfg *Func) const override; 2556 void emitIAS(const Cfg *Func) const override; 2557 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2558 static bool classof(const Inst *Instr) { 2559 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg8b); 2560 } 2561 2562 private: 2563 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx, Variable *Eax, 2564 Variable *Ecx, Variable *Ebx, bool Locked); 2565 }; 2566 2567 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as 2568 /// appropriate. s=float, d=double, i=int. X and Y are determined from 2569 /// dest/src types. Sign and zero extension on the integer operand needs to be 2570 /// done separately. 2571 class InstX86Cvt final : public InstX86Base { 2572 InstX86Cvt() = delete; 2573 InstX86Cvt(const InstX86Cvt &) = delete; 2574 InstX86Cvt &operator=(const InstX86Cvt &) = delete; 2575 2576 public: 2577 enum CvtVariant { Si2ss, Tss2si, Ss2si, Float2float, Dq2ps, Tps2dq, Ps2dq }; create(Cfg * Func,Variable * Dest,Operand * Source,CvtVariant Variant)2578 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 2579 CvtVariant Variant) { 2580 return new (Func->allocate<InstX86Cvt>()) 2581 InstX86Cvt(Func, Dest, Source, Variant); 2582 } 2583 void emit(const Cfg *Func) const override; 2584 void emitIAS(const Cfg *Func) const override; 2585 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2586 static bool classof(const Inst *Instr) { 2587 return InstX86Base::isClassof(Instr, InstX86Base::Cvt); 2588 } isTruncating()2589 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 2590 2591 private: 2592 CvtVariant Variant; 2593 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 2594 }; 2595 2596 /// Round instruction 2597 class InstX86Round final 2598 : public InstX86BaseThreeAddressop<InstX86Base::Round> { 2599 public: create(Cfg * Func,Variable * Dest,Operand * Source,Operand * Imm)2600 static InstX86Round *create(Cfg *Func, Variable *Dest, Operand *Source, 2601 Operand *Imm) { 2602 return new (Func->allocate<InstX86Round>()) 2603 InstX86Round(Func, Dest, Source, Imm); 2604 } 2605 2606 void emit(const Cfg *Func) const override; 2607 void emitIAS(const Cfg *Func) const override; 2608 2609 private: InstX86Round(Cfg * Func,Variable * Dest,Operand * Source,Operand * Imm)2610 InstX86Round(Cfg *Func, Variable *Dest, Operand *Source, Operand *Imm) 2611 : InstX86BaseThreeAddressop<InstX86Base::Round>(Func, Dest, Source, Imm) { 2612 } 2613 }; 2614 2615 /// cmp - Integer compare instruction. 2616 class InstX86Icmp final : public InstX86Base { 2617 InstX86Icmp() = delete; 2618 InstX86Icmp(const InstX86Icmp &) = delete; 2619 InstX86Icmp &operator=(const InstX86Icmp &) = delete; 2620 2621 public: create(Cfg * Func,Operand * Src1,Operand * Src2)2622 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 2623 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2); 2624 } 2625 void emit(const Cfg *Func) const override; 2626 void emitIAS(const Cfg *Func) const override; 2627 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2628 static bool classof(const Inst *Instr) { 2629 return InstX86Base::isClassof(Instr, InstX86Base::Icmp); 2630 } 2631 2632 private: 2633 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 2634 }; 2635 2636 /// ucomiss/ucomisd - floating-point compare instruction. 2637 class InstX86Ucomiss final : public InstX86Base { 2638 InstX86Ucomiss() = delete; 2639 InstX86Ucomiss(const InstX86Ucomiss &) = delete; 2640 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete; 2641 2642 public: create(Cfg * Func,Operand * Src1,Operand * Src2)2643 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 2644 return new (Func->allocate<InstX86Ucomiss>()) 2645 InstX86Ucomiss(Func, Src1, Src2); 2646 } 2647 void emit(const Cfg *Func) const override; 2648 void emitIAS(const Cfg *Func) const override; 2649 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2650 static bool classof(const Inst *Instr) { 2651 return InstX86Base::isClassof(Instr, InstX86Base::Ucomiss); 2652 } 2653 2654 private: 2655 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 2656 }; 2657 2658 /// UD2 instruction. 2659 class InstX86UD2 final : public InstX86Base { 2660 InstX86UD2() = delete; 2661 InstX86UD2(const InstX86UD2 &) = delete; 2662 InstX86UD2 &operator=(const InstX86UD2 &) = delete; 2663 2664 public: create(Cfg * Func)2665 static InstX86UD2 *create(Cfg *Func) { 2666 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func); 2667 } 2668 void emit(const Cfg *Func) const override; 2669 void emitIAS(const Cfg *Func) const override; 2670 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2671 static bool classof(const Inst *Instr) { 2672 return InstX86Base::isClassof(Instr, InstX86Base::UD2); 2673 } 2674 2675 private: 2676 explicit InstX86UD2(Cfg *Func); 2677 }; 2678 2679 /// Int3 instruction. 2680 class InstX86Int3 final : public InstX86Base { 2681 InstX86Int3() = delete; 2682 InstX86Int3(const InstX86Int3 &) = delete; 2683 InstX86Int3 &operator=(const InstX86Int3 &) = delete; 2684 2685 public: create(Cfg * Func)2686 static InstX86Int3 *create(Cfg *Func) { 2687 return new (Func->allocate<InstX86Int3>()) InstX86Int3(Func); 2688 } 2689 void emit(const Cfg *Func) const override; 2690 void emitIAS(const Cfg *Func) const override; 2691 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2692 static bool classof(const Inst *Instr) { 2693 return InstX86Base::isClassof(Instr, InstX86Base::Int3); 2694 } 2695 2696 private: 2697 explicit InstX86Int3(Cfg *Func); 2698 }; 2699 2700 /// Test instruction. 2701 class InstX86Test final : public InstX86Base { 2702 InstX86Test() = delete; 2703 InstX86Test(const InstX86Test &) = delete; 2704 InstX86Test &operator=(const InstX86Test &) = delete; 2705 2706 public: create(Cfg * Func,Operand * Source1,Operand * Source2)2707 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 2708 return new (Func->allocate<InstX86Test>()) 2709 InstX86Test(Func, Source1, Source2); 2710 } 2711 void emit(const Cfg *Func) const override; 2712 void emitIAS(const Cfg *Func) const override; 2713 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2714 static bool classof(const Inst *Instr) { 2715 return InstX86Base::isClassof(Instr, InstX86Base::Test); 2716 } 2717 2718 private: 2719 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2); 2720 }; 2721 2722 /// Mfence instruction. 2723 class InstX86Mfence final : public InstX86Base { 2724 InstX86Mfence() = delete; 2725 InstX86Mfence(const InstX86Mfence &) = delete; 2726 InstX86Mfence &operator=(const InstX86Mfence &) = delete; 2727 2728 public: create(Cfg * Func)2729 static InstX86Mfence *create(Cfg *Func) { 2730 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func); 2731 } 2732 void emit(const Cfg *Func) const override; 2733 void emitIAS(const Cfg *Func) const override; 2734 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2735 static bool classof(const Inst *Instr) { 2736 return InstX86Base::isClassof(Instr, InstX86Base::Mfence); 2737 } 2738 2739 private: 2740 explicit InstX86Mfence(Cfg *Func); 2741 }; 2742 2743 /// This is essentially a "mov" instruction with anX86OperandMem operand 2744 /// instead of Variable as the destination. It's important for liveness that 2745 /// there is no Dest operand. 2746 class InstX86Store final : public InstX86Base { 2747 InstX86Store() = delete; 2748 InstX86Store(const InstX86Store &) = delete; 2749 InstX86Store &operator=(const InstX86Store &) = delete; 2750 2751 public: create(Cfg * Func,Operand * Value,X86Operand * Mem)2752 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) { 2753 return new (Func->allocate<InstX86Store>()) InstX86Store(Func, Value, Mem); 2754 } 2755 void emit(const Cfg *Func) const override; 2756 void emitIAS(const Cfg *Func) const override; 2757 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2758 static bool classof(const Inst *Instr) { 2759 return InstX86Base::isClassof(Instr, InstX86Base::Store); 2760 } 2761 2762 private: 2763 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem); 2764 }; 2765 2766 /// This is essentially a vector "mov" instruction with an X86OperandMem operand 2767 /// instead of Variable as the destination. It's important for liveness that 2768 /// there is no Dest operand. The source must be an Xmm register, since Dest is 2769 /// mem. 2770 class InstX86StoreP final : public InstX86Base { 2771 InstX86StoreP() = delete; 2772 InstX86StoreP(const InstX86StoreP &) = delete; 2773 InstX86StoreP &operator=(const InstX86StoreP &) = delete; 2774 2775 public: create(Cfg * Func,Variable * Value,X86OperandMem * Mem)2776 static InstX86StoreP *create(Cfg *Func, Variable *Value, X86OperandMem *Mem) { 2777 return new (Func->allocate<InstX86StoreP>()) 2778 InstX86StoreP(Func, Value, Mem); 2779 } 2780 void emit(const Cfg *Func) const override; 2781 void emitIAS(const Cfg *Func) const override; 2782 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2783 static bool classof(const Inst *Instr) { 2784 return InstX86Base::isClassof(Instr, InstX86Base::StoreP); 2785 } 2786 2787 private: 2788 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem); 2789 }; 2790 2791 class InstX86StoreQ final : public InstX86Base { 2792 InstX86StoreQ() = delete; 2793 InstX86StoreQ(const InstX86StoreQ &) = delete; 2794 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete; 2795 2796 public: create(Cfg * Func,Operand * Value,X86OperandMem * Mem)2797 static InstX86StoreQ *create(Cfg *Func, Operand *Value, X86OperandMem *Mem) { 2798 return new (Func->allocate<InstX86StoreQ>()) 2799 InstX86StoreQ(Func, Value, Mem); 2800 } 2801 void emit(const Cfg *Func) const override; 2802 void emitIAS(const Cfg *Func) const override; 2803 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2804 static bool classof(const Inst *Instr) { 2805 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ); 2806 } 2807 2808 private: 2809 InstX86StoreQ(Cfg *Func, Operand *Value, X86OperandMem *Mem); 2810 }; 2811 2812 class InstX86StoreD final : public InstX86Base { 2813 InstX86StoreD() = delete; 2814 InstX86StoreD(const InstX86StoreD &) = delete; 2815 InstX86StoreD &operator=(const InstX86StoreD &) = delete; 2816 2817 public: create(Cfg * Func,Operand * Value,X86OperandMem * Mem)2818 static InstX86StoreD *create(Cfg *Func, Operand *Value, X86OperandMem *Mem) { 2819 return new (Func->allocate<InstX86StoreD>()) 2820 InstX86StoreD(Func, Value, Mem); 2821 } 2822 void emit(const Cfg *Func) const override; 2823 void emitIAS(const Cfg *Func) const override; 2824 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2825 static bool classof(const Inst *Instr) { 2826 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ); 2827 } 2828 2829 private: 2830 InstX86StoreD(Cfg *Func, Operand *Value, X86OperandMem *Mem); 2831 }; 2832 2833 /// Nop instructions of varying length 2834 class InstX86Nop final : public InstX86Base { 2835 InstX86Nop() = delete; 2836 InstX86Nop(const InstX86Nop &) = delete; 2837 InstX86Nop &operator=(const InstX86Nop &) = delete; 2838 2839 public: 2840 // TODO: Replace with enum. 2841 using NopVariant = unsigned; 2842 create(Cfg * Func,NopVariant Variant)2843 static InstX86Nop *create(Cfg *Func, NopVariant Variant) { 2844 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant); 2845 } 2846 void emit(const Cfg *Func) const override; 2847 void emitIAS(const Cfg *Func) const override; 2848 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2849 static bool classof(const Inst *Instr) { 2850 return InstX86Base::isClassof(Instr, InstX86Base::Nop); 2851 } 2852 2853 private: 2854 InstX86Nop(Cfg *Func, NopVariant Length); 2855 2856 NopVariant Variant; 2857 }; 2858 2859 /// Fld - load a value onto the x87 FP stack. 2860 class InstX86Fld final : public InstX86Base { 2861 InstX86Fld() = delete; 2862 InstX86Fld(const InstX86Fld &) = delete; 2863 InstX86Fld &operator=(const InstX86Fld &) = delete; 2864 2865 public: create(Cfg * Func,Operand * Src)2866 static InstX86Fld *create(Cfg *Func, Operand *Src) { 2867 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src); 2868 } 2869 void emit(const Cfg *Func) const override; 2870 void emitIAS(const Cfg *Func) const override; 2871 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2872 static bool classof(const Inst *Instr) { 2873 return InstX86Base::isClassof(Instr, InstX86Base::Fld); 2874 } 2875 2876 private: 2877 InstX86Fld(Cfg *Func, Operand *Src); 2878 }; 2879 2880 /// Fstp - store x87 st(0) into memory and pop st(0). 2881 class InstX86Fstp final : public InstX86Base { 2882 InstX86Fstp() = delete; 2883 InstX86Fstp(const InstX86Fstp &) = delete; 2884 InstX86Fstp &operator=(const InstX86Fstp &) = delete; 2885 2886 public: create(Cfg * Func,Variable * Dest)2887 static InstX86Fstp *create(Cfg *Func, Variable *Dest) { 2888 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest); 2889 } 2890 void emit(const Cfg *Func) const override; 2891 void emitIAS(const Cfg *Func) const override; 2892 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2893 static bool classof(const Inst *Instr) { 2894 return InstX86Base::isClassof(Instr, InstX86Base::Fstp); 2895 } 2896 2897 private: 2898 InstX86Fstp(Cfg *Func, Variable *Dest); 2899 }; 2900 2901 class InstX86Pop final : public InstX86Base { 2902 InstX86Pop() = delete; 2903 InstX86Pop(const InstX86Pop &) = delete; 2904 InstX86Pop &operator=(const InstX86Pop &) = delete; 2905 2906 public: create(Cfg * Func,Variable * Dest)2907 static InstX86Pop *create(Cfg *Func, Variable *Dest) { 2908 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest); 2909 } 2910 void emit(const Cfg *Func) const override; 2911 void emitIAS(const Cfg *Func) const override; 2912 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2913 static bool classof(const Inst *Instr) { 2914 return InstX86Base::isClassof(Instr, InstX86Base::Pop); 2915 } 2916 2917 private: 2918 InstX86Pop(Cfg *Func, Variable *Dest); 2919 }; 2920 2921 class InstX86Push final : public InstX86Base { 2922 InstX86Push() = delete; 2923 InstX86Push(const InstX86Push &) = delete; 2924 InstX86Push &operator=(const InstX86Push &) = delete; 2925 2926 public: create(Cfg * Func,Operand * Source)2927 static InstX86Push *create(Cfg *Func, Operand *Source) { 2928 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); 2929 } 2930 void emit(const Cfg *Func) const override; 2931 void emitIAS(const Cfg *Func) const override; 2932 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2933 static bool classof(const Inst *Instr) { 2934 return InstX86Base::isClassof(Instr, InstX86Base::Push); 2935 } 2936 2937 private: 2938 InstX86Push(Cfg *Func, Operand *Source); 2939 }; 2940 2941 /// Ret instruction. Currently only supports the "ret" version that does not 2942 /// pop arguments. This instruction takes a Source operand (for non-void 2943 /// returning functions) for liveness analysis, though a FakeUse before the 2944 /// ret would do just as well. 2945 class InstX86Ret final : public InstX86Base { 2946 InstX86Ret() = delete; 2947 InstX86Ret(const InstX86Ret &) = delete; 2948 InstX86Ret &operator=(const InstX86Ret &) = delete; 2949 2950 public: 2951 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) { 2952 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source); 2953 } 2954 void emit(const Cfg *Func) const override; 2955 void emitIAS(const Cfg *Func) const override; 2956 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2957 static bool classof(const Inst *Instr) { 2958 return InstX86Base::isClassof(Instr, InstX86Base::Ret); 2959 } 2960 2961 private: 2962 InstX86Ret(Cfg *Func, Variable *Source); 2963 }; 2964 2965 /// Conditional set-byte instruction. 2966 class InstX86Setcc final : public InstX86Base { 2967 InstX86Setcc() = delete; 2968 InstX86Setcc(const InstX86Cmov &) = delete; 2969 InstX86Setcc &operator=(const InstX86Setcc &) = delete; 2970 2971 public: create(Cfg * Func,Variable * Dest,BrCond Cond)2972 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) { 2973 return new (Func->allocate<InstX86Setcc>()) InstX86Setcc(Func, Dest, Cond); 2974 } 2975 void emit(const Cfg *Func) const override; 2976 void emitIAS(const Cfg *Func) const override; 2977 void dump(const Cfg *Func) const override; classof(const Inst * Instr)2978 static bool classof(const Inst *Instr) { 2979 return InstX86Base::isClassof(Instr, InstX86Base::Setcc); 2980 } 2981 2982 private: 2983 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond); 2984 2985 const BrCond Condition; 2986 }; 2987 2988 /// Exchanging Add instruction. Exchanges the first operand (destination 2989 /// operand) with the second operand (source operand), then loads the sum of 2990 /// the two values into the destination operand. The destination may be a 2991 /// register or memory, while the source must be a register. 2992 /// 2993 /// Both the dest and source are updated. The caller should then insert a 2994 /// FakeDef to reflect the second udpate. 2995 class InstX86Xadd final : public InstX86BaseLockable { 2996 InstX86Xadd() = delete; 2997 InstX86Xadd(const InstX86Xadd &) = delete; 2998 InstX86Xadd &operator=(const InstX86Xadd &) = delete; 2999 3000 public: create(Cfg * Func,Operand * Dest,Variable * Source,bool Locked)3001 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 3002 bool Locked) { 3003 return new (Func->allocate<InstX86Xadd>()) 3004 InstX86Xadd(Func, Dest, Source, Locked); 3005 } 3006 void emit(const Cfg *Func) const override; 3007 void emitIAS(const Cfg *Func) const override; 3008 void dump(const Cfg *Func) const override; classof(const Inst * Instr)3009 static bool classof(const Inst *Instr) { 3010 return InstX86Base::isClassof(Instr, InstX86Base::Xadd); 3011 } 3012 3013 private: 3014 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 3015 }; 3016 3017 /// Exchange instruction. Exchanges the first operand (destination operand) 3018 /// with the second operand (source operand). At least one of the operands 3019 /// must be a register (and the other can be reg or mem). Both the Dest and 3020 /// Source are updated. If there is a memory operand, then the instruction is 3021 /// automatically "locked" without the need for a lock prefix. 3022 class InstX86Xchg final : public InstX86Base { 3023 InstX86Xchg() = delete; 3024 InstX86Xchg(const InstX86Xchg &) = delete; 3025 InstX86Xchg &operator=(const InstX86Xchg &) = delete; 3026 3027 public: create(Cfg * Func,Operand * Dest,Variable * Source)3028 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 3029 return new (Func->allocate<InstX86Xchg>()) InstX86Xchg(Func, Dest, Source); 3030 } 3031 void emit(const Cfg *Func) const override; 3032 void emitIAS(const Cfg *Func) const override; 3033 void dump(const Cfg *Func) const override; classof(const Inst * Instr)3034 static bool classof(const Inst *Instr) { 3035 return InstX86Base::isClassof(Instr, InstX86Base::Xchg); 3036 } 3037 3038 private: 3039 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source); 3040 }; 3041 3042 /// Start marker for the Intel Architecture Code Analyzer. This is not an 3043 /// executable instruction and must only be used for analysis. 3044 class InstX86IacaStart final : public InstX86Base { 3045 InstX86IacaStart() = delete; 3046 InstX86IacaStart(const InstX86IacaStart &) = delete; 3047 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete; 3048 3049 public: create(Cfg * Func)3050 static InstX86IacaStart *create(Cfg *Func) { 3051 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func); 3052 } 3053 void emit(const Cfg *Func) const override; 3054 void emitIAS(const Cfg *Func) const override; 3055 void dump(const Cfg *Func) const override; classof(const Inst * Instr)3056 static bool classof(const Inst *Instr) { 3057 return InstX86Base::isClassof(Instr, InstX86Base::IacaStart); 3058 } 3059 3060 private: 3061 InstX86IacaStart(Cfg *Func); 3062 }; 3063 3064 /// End marker for the Intel Architecture Code Analyzer. This is not an 3065 /// executable instruction and must only be used for analysis. 3066 class InstX86IacaEnd final : public InstX86Base { 3067 InstX86IacaEnd() = delete; 3068 InstX86IacaEnd(const InstX86IacaEnd &) = delete; 3069 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete; 3070 3071 public: create(Cfg * Func)3072 static InstX86IacaEnd *create(Cfg *Func) { 3073 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func); 3074 } 3075 void emit(const Cfg *Func) const override; 3076 void emitIAS(const Cfg *Func) const override; 3077 void dump(const Cfg *Func) const override; classof(const Inst * Instr)3078 static bool classof(const Inst *Instr) { 3079 return InstX86Base::isClassof(Instr, InstX86Base::IacaEnd); 3080 } 3081 3082 private: 3083 InstX86IacaEnd(Cfg *Func); 3084 }; 3085 3086 class InstX86Pshufb : public InstX86BaseBinopXmm<InstX86Base::Pshufb, false, 3087 InstX86Base::SseSuffix::None> { 3088 public: create(Cfg * Func,Variable * Dest,Operand * Source)3089 static InstX86Pshufb *create(Cfg *Func, Variable *Dest, Operand *Source) { 3090 return new (Func->allocate<InstX86Pshufb>()) 3091 InstX86Pshufb(Func, Dest, Source); 3092 } 3093 3094 private: InstX86Pshufb(Cfg * Func,Variable * Dest,Operand * Source)3095 InstX86Pshufb(Cfg *Func, Variable *Dest, Operand *Source) 3096 : InstX86BaseBinopXmm<InstX86Base::Pshufb, false, 3097 InstX86Base::SseSuffix::None>(Func, Dest, Source) {} 3098 }; 3099 3100 class InstX86Punpckl 3101 : public InstX86BaseBinopXmm<InstX86Base::Punpckl, false, 3102 InstX86Base::SseSuffix::Unpack> { 3103 public: create(Cfg * Func,Variable * Dest,Operand * Source)3104 static InstX86Punpckl *create(Cfg *Func, Variable *Dest, Operand *Source) { 3105 return new (Func->allocate<InstX86Punpckl>()) 3106 InstX86Punpckl(Func, Dest, Source); 3107 } 3108 3109 private: InstX86Punpckl(Cfg * Func,Variable * Dest,Operand * Source)3110 InstX86Punpckl(Cfg *Func, Variable *Dest, Operand *Source) 3111 : InstX86BaseBinopXmm<InstX86Base::Punpckl, false, 3112 InstX86Base::SseSuffix::Unpack>(Func, Dest, 3113 Source) {} 3114 }; 3115 3116 class InstX86Punpckh 3117 : public InstX86BaseBinopXmm<InstX86Base::Punpckh, false, 3118 InstX86Base::SseSuffix::Unpack> { 3119 public: create(Cfg * Func,Variable * Dest,Operand * Source)3120 static InstX86Punpckh *create(Cfg *Func, Variable *Dest, Operand *Source) { 3121 return new (Func->allocate<InstX86Punpckh>()) 3122 InstX86Punpckh(Func, Dest, Source); 3123 } 3124 3125 private: InstX86Punpckh(Cfg * Func,Variable * Dest,Operand * Source)3126 InstX86Punpckh(Cfg *Func, Variable *Dest, Operand *Source) 3127 : InstX86BaseBinopXmm<InstX86Base::Punpckh, false, 3128 InstX86Base::SseSuffix::Unpack>(Func, Dest, 3129 Source) {} 3130 }; 3131 3132 class InstX86Packss : public InstX86BaseBinopXmm<InstX86Base::Packss, false, 3133 InstX86Base::SseSuffix::Pack> { 3134 public: create(Cfg * Func,Variable * Dest,Operand * Source)3135 static InstX86Packss *create(Cfg *Func, Variable *Dest, Operand *Source) { 3136 return new (Func->allocate<InstX86Packss>()) 3137 InstX86Packss(Func, Dest, Source); 3138 } 3139 3140 private: InstX86Packss(Cfg * Func,Variable * Dest,Operand * Source)3141 InstX86Packss(Cfg *Func, Variable *Dest, Operand *Source) 3142 : InstX86BaseBinopXmm<InstX86Base::Packss, false, 3143 InstX86Base::SseSuffix::Pack>(Func, Dest, Source) {} 3144 }; 3145 3146 class InstX86Packus : public InstX86BaseBinopXmm<InstX86Base::Packus, false, 3147 InstX86Base::SseSuffix::Pack> { 3148 public: create(Cfg * Func,Variable * Dest,Operand * Source)3149 static InstX86Packus *create(Cfg *Func, Variable *Dest, Operand *Source) { 3150 return new (Func->allocate<InstX86Packus>()) 3151 InstX86Packus(Func, Dest, Source); 3152 } 3153 3154 private: InstX86Packus(Cfg * Func,Variable * Dest,Operand * Source)3155 InstX86Packus(Cfg *Func, Variable *Dest, Operand *Source) 3156 : InstX86BaseBinopXmm<InstX86Base::Packus, false, 3157 InstX86Base::SseSuffix::Pack>(Func, Dest, Source) {} 3158 }; 3159 3160 struct Insts { 3161 using FakeRMW = InstX86FakeRMW; 3162 using Label = InstX86Label; 3163 3164 using Call = InstX86Call; 3165 3166 using Br = InstX86Br; 3167 using Jmp = InstX86Jmp; 3168 using Bswap = InstX86Bswap; 3169 using Neg = InstX86Neg; 3170 using Bsf = InstX86Bsf; 3171 using Bsr = InstX86Bsr; 3172 using Lea = InstX86Lea; 3173 using Cbwdq = InstX86Cbwdq; 3174 using Movsx = InstX86Movsx; 3175 using Movzx = InstX86Movzx; 3176 using Movd = InstX86Movd; 3177 using Movmsk = InstX86Movmsk; 3178 using Sqrt = InstX86Sqrt; 3179 using Mov = InstX86Mov; 3180 using Movp = InstX86Movp; 3181 using Movq = InstX86Movq; 3182 using Add = InstX86Add; 3183 using AddRMW = InstX86AddRMW; 3184 using Addps = InstX86Addps; 3185 using Adc = InstX86Adc; 3186 using AdcRMW = InstX86AdcRMW; 3187 using Addss = InstX86Addss; 3188 using Andnps = InstX86Andnps; 3189 using Andps = InstX86Andps; 3190 using Padd = InstX86Padd; 3191 using Padds = InstX86Padds; 3192 using Paddus = InstX86Paddus; 3193 using Sub = InstX86Sub; 3194 using SubRMW = InstX86SubRMW; 3195 using Subps = InstX86Subps; 3196 using Subss = InstX86Subss; 3197 using Sbb = InstX86Sbb; 3198 using SbbRMW = InstX86SbbRMW; 3199 using Psub = InstX86Psub; 3200 using Psubs = InstX86Psubs; 3201 using Psubus = InstX86Psubus; 3202 using And = InstX86And; 3203 using AndRMW = InstX86AndRMW; 3204 using Pand = InstX86Pand; 3205 using Pandn = InstX86Pandn; 3206 using Or = InstX86Or; 3207 using Orps = InstX86Orps; 3208 using OrRMW = InstX86OrRMW; 3209 using Por = InstX86Por; 3210 using Xor = InstX86Xor; 3211 using Xorps = InstX86Xorps; 3212 using XorRMW = InstX86XorRMW; 3213 using Pxor = InstX86Pxor; 3214 using Maxss = InstX86Maxss; 3215 using Minss = InstX86Minss; 3216 using Maxps = InstX86Maxps; 3217 using Minps = InstX86Minps; 3218 using Imul = InstX86Imul; 3219 using ImulImm = InstX86ImulImm; 3220 using Mulps = InstX86Mulps; 3221 using Mulss = InstX86Mulss; 3222 using Pmull = InstX86Pmull; 3223 using Pmulhw = InstX86Pmulhw; 3224 using Pmulhuw = InstX86Pmulhuw; 3225 using Pmaddwd = InstX86Pmaddwd; 3226 using Pmuludq = InstX86Pmuludq; 3227 using Divps = InstX86Divps; 3228 using Divss = InstX86Divss; 3229 using Rol = InstX86Rol; 3230 using Shl = InstX86Shl; 3231 using Psll = InstX86Psll; 3232 using Psrl = InstX86Psrl; 3233 using Shr = InstX86Shr; 3234 using Sar = InstX86Sar; 3235 using Psra = InstX86Psra; 3236 using Pcmpeq = InstX86Pcmpeq; 3237 using Pcmpgt = InstX86Pcmpgt; 3238 using MovssRegs = InstX86MovssRegs; 3239 using Idiv = InstX86Idiv; 3240 using Div = InstX86Div; 3241 using Insertps = InstX86Insertps; 3242 using Pinsr = InstX86Pinsr; 3243 using Shufps = InstX86Shufps; 3244 using Blendvps = InstX86Blendvps; 3245 using Pblendvb = InstX86Pblendvb; 3246 using Pextr = InstX86Pextr; 3247 using Pshufd = InstX86Pshufd; 3248 using Lockable = InstX86BaseLockable; 3249 using Mul = InstX86Mul; 3250 using Shld = InstX86Shld; 3251 using Shrd = InstX86Shrd; 3252 using Cmov = InstX86Cmov; 3253 using Cmpps = InstX86Cmpps; 3254 using Cmpxchg = InstX86Cmpxchg; 3255 using Cmpxchg8b = InstX86Cmpxchg8b; 3256 using Cvt = InstX86Cvt; 3257 using Round = InstX86Round; 3258 using Icmp = InstX86Icmp; 3259 using Ucomiss = InstX86Ucomiss; 3260 using UD2 = InstX86UD2; 3261 using Int3 = InstX86Int3; 3262 using Test = InstX86Test; 3263 using Mfence = InstX86Mfence; 3264 using Store = InstX86Store; 3265 using StoreP = InstX86StoreP; 3266 using StoreQ = InstX86StoreQ; 3267 using StoreD = InstX86StoreD; 3268 using Nop = InstX86Nop; 3269 using Fld = InstX86Fld; 3270 using Fstp = InstX86Fstp; 3271 using Pop = InstX86Pop; 3272 using Push = InstX86Push; 3273 using Ret = InstX86Ret; 3274 using Setcc = InstX86Setcc; 3275 using Xadd = InstX86Xadd; 3276 using Xchg = InstX86Xchg; 3277 3278 using IacaStart = InstX86IacaStart; 3279 using IacaEnd = InstX86IacaEnd; 3280 3281 using Pshufb = InstX86Pshufb; 3282 using Punpckl = InstX86Punpckl; 3283 using Punpckh = InstX86Punpckh; 3284 using Packss = InstX86Packss; 3285 using Packus = InstX86Packus; 3286 }; 3287 3288 /// X86 Instructions have static data (particularly, opcodes and instruction 3289 /// emitters). Each X86 target needs to define all of these, so this macro is 3290 /// provided so that, if something changes, then all X86 targets will be updated 3291 /// automatically. 3292 /* In-place ops */ 3293 template <> constexpr const char *InstX86Bswap::Base::Opcode = "bswap"; 3294 template <> constexpr const char *InstX86Neg::Base::Opcode = "neg"; 3295 /* Unary ops */ 3296 template <> constexpr const char *InstX86Bsf::Base::Opcode = "bsf"; 3297 template <> constexpr const char *InstX86Bsr::Base::Opcode = "bsr"; 3298 template <> constexpr const char *InstX86Lea::Base::Opcode = "lea"; 3299 template <> constexpr const char *InstX86Movd::Base::Opcode = "movd"; 3300 template <> constexpr const char *InstX86Movsx::Base::Opcode = "movs"; 3301 template <> constexpr const char *InstX86Movzx::Base::Opcode = "movz"; 3302 template <> constexpr const char *InstX86Sqrt::Base::Opcode = "sqrt"; 3303 template <> constexpr const char *InstX86Cbwdq::Base::Opcode = "cbw/cwd/cdq"; 3304 /* Mov-like ops */ 3305 template <> constexpr const char *InstX86Mov::Base::Opcode = "mov"; 3306 template <> constexpr const char *InstX86Movp::Base::Opcode = "movups"; 3307 template <> constexpr const char *InstX86Movq::Base::Opcode = "movq"; 3308 /* Binary ops */ 3309 template <> constexpr const char *InstX86Add::Base::Opcode = "add"; 3310 template <> constexpr const char *InstX86AddRMW::Base::Opcode = "add"; 3311 template <> constexpr const char *InstX86Addps::Base::Opcode = "add"; 3312 template <> constexpr const char *InstX86Adc::Base::Opcode = "adc"; 3313 template <> constexpr const char *InstX86AdcRMW::Base::Opcode = "adc"; 3314 template <> constexpr const char *InstX86Addss::Base::Opcode = "add"; 3315 template <> constexpr const char *InstX86Andnps::Base::Opcode = "andn"; 3316 template <> constexpr const char *InstX86Andps::Base::Opcode = "and"; 3317 template <> constexpr const char *InstX86Maxss::Base::Opcode = "max"; 3318 template <> constexpr const char *InstX86Minss::Base::Opcode = "min"; 3319 template <> constexpr const char *InstX86Maxps::Base::Opcode = "max"; 3320 template <> constexpr const char *InstX86Minps::Base::Opcode = "min"; 3321 template <> constexpr const char *InstX86Padd::Base::Opcode = "padd"; 3322 template <> constexpr const char *InstX86Padds::Base::Opcode = "padds"; 3323 template <> constexpr const char *InstX86Paddus::Base::Opcode = "paddus"; 3324 template <> constexpr const char *InstX86Sub::Base::Opcode = "sub"; 3325 template <> constexpr const char *InstX86SubRMW::Base::Opcode = "sub"; 3326 template <> constexpr const char *InstX86Subps::Base::Opcode = "sub"; 3327 template <> constexpr const char *InstX86Subss::Base::Opcode = "sub"; 3328 template <> constexpr const char *InstX86Sbb::Base::Opcode = "sbb"; 3329 template <> constexpr const char *InstX86SbbRMW::Base::Opcode = "sbb"; 3330 template <> constexpr const char *InstX86Psub::Base::Opcode = "psub"; 3331 template <> constexpr const char *InstX86Psubs::Base::Opcode = "psubs"; 3332 template <> constexpr const char *InstX86Psubus::Base::Opcode = "psubus"; 3333 template <> constexpr const char *InstX86And::Base::Opcode = "and"; 3334 template <> constexpr const char *InstX86AndRMW::Base::Opcode = "and"; 3335 template <> constexpr const char *InstX86Pand::Base::Opcode = "pand"; 3336 template <> constexpr const char *InstX86Pandn::Base::Opcode = "pandn"; 3337 template <> constexpr const char *InstX86Or::Base::Opcode = "or"; 3338 template <> constexpr const char *InstX86Orps::Base::Opcode = "or"; 3339 template <> constexpr const char *InstX86OrRMW::Base::Opcode = "or"; 3340 template <> constexpr const char *InstX86Por::Base::Opcode = "por"; 3341 template <> constexpr const char *InstX86Xor::Base::Opcode = "xor"; 3342 template <> constexpr const char *InstX86Xorps::Base::Opcode = "xor"; 3343 template <> constexpr const char *InstX86XorRMW::Base::Opcode = "xor"; 3344 template <> constexpr const char *InstX86Pxor::Base::Opcode = "pxor"; 3345 template <> constexpr const char *InstX86Imul::Base::Opcode = "imul"; 3346 template <> constexpr const char *InstX86ImulImm::Base::Opcode = "imul"; 3347 template <> constexpr const char *InstX86Mulps::Base::Opcode = "mul"; 3348 template <> constexpr const char *InstX86Mulss::Base::Opcode = "mul"; 3349 template <> constexpr const char *InstX86Pmull::Base::Opcode = "pmull"; 3350 template <> constexpr const char *InstX86Pmulhw::Base::Opcode = "pmulhw"; 3351 template <> constexpr const char *InstX86Pmulhuw::Base::Opcode = "pmulhuw"; 3352 template <> constexpr const char *InstX86Pmaddwd::Base::Opcode = "pmaddwd"; 3353 template <> constexpr const char *InstX86Pmuludq::Base::Opcode = "pmuludq"; 3354 template <> constexpr const char *InstX86Div::Base::Opcode = "div"; 3355 template <> constexpr const char *InstX86Divps::Base::Opcode = "div"; 3356 template <> constexpr const char *InstX86Divss::Base::Opcode = "div"; 3357 template <> constexpr const char *InstX86Idiv::Base::Opcode = "idiv"; 3358 template <> constexpr const char *InstX86Rol::Base::Opcode = "rol"; 3359 template <> constexpr const char *InstX86Shl::Base::Opcode = "shl"; 3360 template <> constexpr const char *InstX86Psll::Base::Opcode = "psll"; 3361 template <> constexpr const char *InstX86Shr::Base::Opcode = "shr"; 3362 template <> constexpr const char *InstX86Sar::Base::Opcode = "sar"; 3363 template <> constexpr const char *InstX86Psra::Base::Opcode = "psra"; 3364 template <> constexpr const char *InstX86Psrl::Base::Opcode = "psrl"; 3365 template <> constexpr const char *InstX86Pcmpeq::Base::Opcode = "pcmpeq"; 3366 template <> constexpr const char *InstX86Pcmpgt::Base::Opcode = "pcmpgt"; 3367 template <> constexpr const char *InstX86MovssRegs::Base::Opcode = "movss"; 3368 /* Ternary ops */ 3369 template <> constexpr const char *InstX86Insertps::Base::Opcode = "insertps"; 3370 template <> constexpr const char *InstX86Round::Base::Opcode = "round"; 3371 template <> constexpr const char *InstX86Shufps::Base::Opcode = "shufps"; 3372 template <> constexpr const char *InstX86Pinsr::Base::Opcode = "pinsr"; 3373 template <> constexpr const char *InstX86Blendvps::Base::Opcode = "blendvps"; 3374 template <> constexpr const char *InstX86Pblendvb::Base::Opcode = "pblendvb"; 3375 /* Three address ops */ 3376 template <> constexpr const char *InstX86Pextr::Base::Opcode = "pextr"; 3377 template <> constexpr const char *InstX86Pshufd::Base::Opcode = "pshufd"; 3378 template <> constexpr const char *InstX86Pshufb::Base::Opcode = "pshufb"; 3379 template <> constexpr const char *InstX86Punpckl::Base::Opcode = "punpckl"; 3380 template <> constexpr const char *InstX86Punpckh::Base::Opcode = "punpckh"; 3381 template <> constexpr const char *InstX86Packss::Base::Opcode = "packss"; 3382 template <> constexpr const char *InstX86Packus::Base::Opcode = "packus"; 3383 /* Inplace GPR ops */ 3384 template <> 3385 constexpr const Assembler::GPREmitterOneOp InstX86Bswap::Base::Emitter = { 3386 &Assembler::bswap, nullptr /* only a reg form exists */ 3387 }; 3388 template <> 3389 constexpr const Assembler::GPREmitterOneOp InstX86Neg::Base::Emitter = { 3390 &Assembler::neg, &Assembler::neg}; 3391 /* Unary GPR ops */ 3392 /* uses specialized emitter. */ 3393 template <> 3394 constexpr const Assembler::GPREmitterRegOp InstX86Cbwdq::Base::Emitter = { 3395 nullptr, nullptr, nullptr}; 3396 template <> 3397 constexpr const Assembler::GPREmitterRegOp InstX86Bsf::Base::Emitter = { 3398 &Assembler::bsf, &Assembler::bsf, nullptr}; 3399 template <> 3400 constexpr const Assembler::GPREmitterRegOp InstX86Bsr::Base::Emitter = { 3401 &Assembler::bsr, &Assembler::bsr, nullptr}; 3402 template <> 3403 constexpr const Assembler::GPREmitterRegOp InstX86Lea::Base::Emitter = { 3404 /* reg/reg and reg/imm are illegal */ nullptr, &Assembler::lea, nullptr}; 3405 template <> 3406 constexpr const Assembler::GPREmitterRegOp InstX86Movsx::Base::Emitter = { 3407 &Assembler::movsx, &Assembler::movsx, nullptr}; 3408 template <> 3409 constexpr const Assembler::GPREmitterRegOp InstX86Movzx::Base::Emitter = { 3410 &Assembler::movzx, &Assembler::movzx, nullptr}; 3411 /* Unary XMM ops */ 3412 /* uses specialized emitter. */ 3413 template <> 3414 constexpr const Assembler::XmmEmitterRegOp InstX86Movd::Base::Emitter = { 3415 nullptr, nullptr}; 3416 template <> 3417 constexpr const Assembler::XmmEmitterRegOp InstX86Sqrt::Base::Emitter = { 3418 &Assembler::sqrt, &Assembler::sqrt}; 3419 /* Binary GPR ops */ 3420 /* uses specialized emitter. */ 3421 template <> 3422 constexpr const Assembler::GPREmitterRegOp InstX86Imul::Base::Emitter = { 3423 nullptr, nullptr, nullptr}; 3424 template <> 3425 constexpr const Assembler::GPREmitterRegOp InstX86Add::Base::Emitter = { 3426 &Assembler::add, &Assembler::add, &Assembler::add}; 3427 template <> 3428 constexpr const Assembler::GPREmitterAddrOp InstX86AddRMW::Base::Emitter = { 3429 &Assembler::add, &Assembler::add}; 3430 template <> 3431 constexpr const Assembler::GPREmitterRegOp InstX86Adc::Base::Emitter = { 3432 &Assembler::adc, &Assembler::adc, &Assembler::adc}; 3433 template <> 3434 constexpr const Assembler::GPREmitterAddrOp InstX86AdcRMW::Base::Emitter = { 3435 &Assembler::adc, &Assembler::adc}; 3436 template <> 3437 constexpr const Assembler::GPREmitterRegOp InstX86And::Base::Emitter = { 3438 &Assembler::And, &Assembler::And, &Assembler::And}; 3439 template <> 3440 constexpr const Assembler::GPREmitterAddrOp InstX86AndRMW::Base::Emitter = { 3441 &Assembler::And, &Assembler::And}; 3442 template <> 3443 constexpr const Assembler::GPREmitterRegOp InstX86Or::Base::Emitter = { 3444 &Assembler::Or, &Assembler::Or, &Assembler::Or}; 3445 template <> 3446 constexpr const Assembler::GPREmitterAddrOp InstX86OrRMW::Base::Emitter = { 3447 &Assembler::Or, &Assembler::Or}; 3448 template <> 3449 constexpr const Assembler::GPREmitterRegOp InstX86Sbb::Base::Emitter = { 3450 &Assembler::sbb, &Assembler::sbb, &Assembler::sbb}; 3451 template <> 3452 constexpr const Assembler::GPREmitterAddrOp InstX86SbbRMW::Base::Emitter = { 3453 &Assembler::sbb, &Assembler::sbb}; 3454 template <> 3455 constexpr const Assembler::GPREmitterRegOp InstX86Sub::Base::Emitter = { 3456 &Assembler::sub, &Assembler::sub, &Assembler::sub}; 3457 template <> 3458 constexpr const Assembler::GPREmitterAddrOp InstX86SubRMW::Base::Emitter = { 3459 &Assembler::sub, &Assembler::sub}; 3460 template <> 3461 constexpr const Assembler::GPREmitterRegOp InstX86Xor::Base::Emitter = { 3462 &Assembler::Xor, &Assembler::Xor, &Assembler::Xor}; 3463 template <> 3464 constexpr const Assembler::GPREmitterAddrOp InstX86XorRMW::Base::Emitter = { 3465 &Assembler::Xor, &Assembler::Xor}; 3466 /* Binary Shift GPR ops */ 3467 template <> 3468 constexpr const Assembler::GPREmitterShiftOp InstX86Rol::Base::Emitter = { 3469 &Assembler::rol, &Assembler::rol}; 3470 template <> 3471 constexpr const Assembler::GPREmitterShiftOp InstX86Sar::Base::Emitter = { 3472 &Assembler::sar, &Assembler::sar}; 3473 template <> 3474 constexpr const Assembler::GPREmitterShiftOp InstX86Shl::Base::Emitter = { 3475 &Assembler::shl, &Assembler::shl}; 3476 template <> 3477 constexpr const Assembler::GPREmitterShiftOp InstX86Shr::Base::Emitter = { 3478 &Assembler::shr, &Assembler::shr}; 3479 /* Binary XMM ops */ 3480 /* uses specialized emitter. */ 3481 template <> 3482 constexpr const Assembler::XmmEmitterRegOp InstX86MovssRegs::Base::Emitter = { 3483 nullptr, nullptr}; 3484 template <> 3485 constexpr const Assembler::XmmEmitterRegOp InstX86Addss::Base::Emitter = { 3486 &Assembler::addss, &Assembler::addss}; 3487 template <> 3488 constexpr const Assembler::XmmEmitterRegOp InstX86Addps::Base::Emitter = { 3489 &Assembler::addps, &Assembler::addps}; 3490 template <> 3491 constexpr const Assembler::XmmEmitterRegOp InstX86Divss::Base::Emitter = { 3492 &Assembler::divss, &Assembler::divss}; 3493 template <> 3494 constexpr const Assembler::XmmEmitterRegOp InstX86Divps::Base::Emitter = { 3495 &Assembler::divps, &Assembler::divps}; 3496 template <> 3497 constexpr const Assembler::XmmEmitterRegOp InstX86Mulss::Base::Emitter = { 3498 &Assembler::mulss, &Assembler::mulss}; 3499 template <> 3500 constexpr const Assembler::XmmEmitterRegOp InstX86Mulps::Base::Emitter = { 3501 &Assembler::mulps, &Assembler::mulps}; 3502 template <> 3503 constexpr const Assembler::XmmEmitterRegOp InstX86Padd::Base::Emitter = { 3504 &Assembler::padd, &Assembler::padd}; 3505 template <> 3506 constexpr const Assembler::XmmEmitterRegOp InstX86Padds::Base::Emitter = { 3507 &Assembler::padds, &Assembler::padds}; 3508 template <> 3509 constexpr const Assembler::XmmEmitterRegOp InstX86Paddus::Base::Emitter = { 3510 &Assembler::paddus, &Assembler::paddus}; 3511 template <> 3512 constexpr const Assembler::XmmEmitterRegOp InstX86Pand::Base::Emitter = { 3513 &Assembler::pand, &Assembler::pand}; 3514 template <> 3515 constexpr const Assembler::XmmEmitterRegOp InstX86Pandn::Base::Emitter = { 3516 &Assembler::pandn, &Assembler::pandn}; 3517 template <> 3518 constexpr const Assembler::XmmEmitterRegOp InstX86Pcmpeq::Base::Emitter = { 3519 &Assembler::pcmpeq, &Assembler::pcmpeq}; 3520 template <> 3521 constexpr const Assembler::XmmEmitterRegOp InstX86Pcmpgt::Base::Emitter = { 3522 &Assembler::pcmpgt, &Assembler::pcmpgt}; 3523 template <> 3524 constexpr const Assembler::XmmEmitterRegOp InstX86Pmull::Base::Emitter = { 3525 &Assembler::pmull, &Assembler::pmull}; 3526 template <> 3527 constexpr const Assembler::XmmEmitterRegOp InstX86Pmulhw::Base::Emitter = { 3528 &Assembler::pmulhw, &Assembler::pmulhw}; 3529 template <> 3530 constexpr const Assembler::XmmEmitterRegOp InstX86Pmulhuw::Base::Emitter = { 3531 &Assembler::pmulhuw, &Assembler::pmulhuw}; 3532 template <> 3533 constexpr const Assembler::XmmEmitterRegOp InstX86Pmaddwd::Base::Emitter = { 3534 &Assembler::pmaddwd, &Assembler::pmaddwd}; 3535 template <> 3536 constexpr const Assembler::XmmEmitterRegOp InstX86Pmuludq::Base::Emitter = { 3537 &Assembler::pmuludq, &Assembler::pmuludq}; 3538 template <> 3539 constexpr const Assembler::XmmEmitterRegOp InstX86Por::Base::Emitter = { 3540 &Assembler::por, &Assembler::por}; 3541 template <> 3542 constexpr const Assembler::XmmEmitterRegOp InstX86Psub::Base::Emitter = { 3543 &Assembler::psub, &Assembler::psub}; 3544 template <> 3545 constexpr const Assembler::XmmEmitterRegOp InstX86Psubs::Base::Emitter = { 3546 &Assembler::psubs, &Assembler::psubs}; 3547 template <> 3548 constexpr const Assembler::XmmEmitterRegOp InstX86Psubus::Base::Emitter = { 3549 &Assembler::psubus, &Assembler::psubus}; 3550 template <> 3551 constexpr const Assembler::XmmEmitterRegOp InstX86Pxor::Base::Emitter = { 3552 &Assembler::pxor, &Assembler::pxor}; 3553 template <> 3554 constexpr const Assembler::XmmEmitterRegOp InstX86Subss::Base::Emitter = { 3555 &Assembler::subss, &Assembler::subss}; 3556 template <> 3557 constexpr const Assembler::XmmEmitterRegOp InstX86Subps::Base::Emitter = { 3558 &Assembler::subps, &Assembler::subps}; 3559 template <> 3560 constexpr const Assembler::XmmEmitterRegOp InstX86Andnps::Base::Emitter = { 3561 &Assembler::andnps, &Assembler::andnps}; 3562 template <> 3563 constexpr const Assembler::XmmEmitterRegOp InstX86Andps::Base::Emitter = { 3564 &Assembler::andps, &Assembler::andps}; 3565 template <> 3566 constexpr const Assembler::XmmEmitterRegOp InstX86Maxss::Base::Emitter = { 3567 &Assembler::maxss, &Assembler::maxss}; 3568 template <> 3569 constexpr const Assembler::XmmEmitterRegOp InstX86Minss::Base::Emitter = { 3570 &Assembler::minss, &Assembler::minss}; 3571 template <> 3572 constexpr const Assembler::XmmEmitterRegOp InstX86Maxps::Base::Emitter = { 3573 &Assembler::maxps, &Assembler::maxps}; 3574 template <> 3575 constexpr const Assembler::XmmEmitterRegOp InstX86Minps::Base::Emitter = { 3576 &Assembler::minps, &Assembler::minps}; 3577 template <> 3578 constexpr const Assembler::XmmEmitterRegOp InstX86Orps::Base::Emitter = { 3579 &Assembler::orps, &Assembler::orps}; 3580 template <> 3581 constexpr const Assembler::XmmEmitterRegOp InstX86Xorps::Base::Emitter = { 3582 &Assembler::xorps, &Assembler::xorps}; /* Binary XMM Shift ops */ 3583 template <> 3584 constexpr const Assembler::XmmEmitterShiftOp InstX86Psll::Base::Emitter = { 3585 &Assembler::psll, &Assembler::psll, &Assembler::psll}; 3586 template <> 3587 constexpr const Assembler::XmmEmitterShiftOp InstX86Psra::Base::Emitter = { 3588 &Assembler::psra, &Assembler::psra, &Assembler::psra}; 3589 template <> 3590 constexpr const Assembler::XmmEmitterShiftOp InstX86Psrl::Base::Emitter = { 3591 &Assembler::psrl, &Assembler::psrl, &Assembler::psrl}; 3592 template <> 3593 constexpr const Assembler::XmmEmitterRegOp InstX86Pshufb::Base::Emitter = { 3594 &Assembler::pshufb, &Assembler::pshufb}; 3595 template <> 3596 constexpr const Assembler::XmmEmitterRegOp InstX86Punpckl::Base::Emitter = { 3597 &Assembler::punpckl, &Assembler::punpckl}; 3598 template <> 3599 constexpr const Assembler::XmmEmitterRegOp InstX86Punpckh::Base::Emitter = { 3600 &Assembler::punpckh, &Assembler::punpckh}; 3601 template <> 3602 constexpr const Assembler::XmmEmitterRegOp InstX86Packss::Base::Emitter = { 3603 &Assembler::packss, &Assembler::packss}; 3604 template <> 3605 constexpr const Assembler::XmmEmitterRegOp InstX86Packus::Base::Emitter = { 3606 &Assembler::packus, &Assembler::packus}; 3607 3608 } // end of namespace X8632 3609 } // end of namespace Ice 3610 3611 #endif // SUBZERO_SRC_ICEINSTX8632_H 3612