Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Side by Side Diff: src/IceInstX86Base.h

Issue 1665423002: Subzero: Cleanup Inst==>Instr. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstARM32.cpp ('k') | src/IceInstX86BaseImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===// 1 //===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 const char *Suffix = "") const; 194 const char *Suffix = "") const;
195 195
196 static TargetLowering *getTarget(const Cfg *Func) { 196 static TargetLowering *getTarget(const Cfg *Func) {
197 return static_cast<TargetLowering *>(Func->getTarget()); 197 return static_cast<TargetLowering *>(Func->getTarget());
198 } 198 }
199 199
200 protected: 200 protected:
201 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest) 201 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest)
202 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 202 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
203 203
204 static bool isClassof(const Inst *Inst, InstKindX86 MyKind) { 204 static bool isClassof(const Inst *Instr, InstKindX86 MyKind) {
205 return Inst->getKind() == static_cast<InstKind>(MyKind); 205 return Instr->getKind() == static_cast<InstKind>(MyKind);
206 } 206 }
207 // Most instructions that operate on vector arguments require vector memory 207 // Most instructions that operate on vector arguments require vector memory
208 // operands to be fully aligned (16-byte alignment for PNaCl vector types). 208 // operands to be fully aligned (16-byte alignment for PNaCl vector types).
209 // The stack frame layout and call ABI ensure proper alignment for stack 209 // The stack frame layout and call ABI ensure proper alignment for stack
210 // operands, but memory operands (originating from load/store bitcode 210 // operands, but memory operands (originating from load/store bitcode
211 // instructions) only have element-size alignment guarantees. This function 211 // instructions) only have element-size alignment guarantees. This function
212 // validates that none of the operands is a memory operand of vector type, 212 // validates that none of the operands is a memory operand of vector type,
213 // calling report_fatal_error() if one is found. This function should be 213 // calling report_fatal_error() if one is found. This function should be
214 // called during emission, and maybe also in the ctor (as long as that fits 214 // called during emission, and maybe also in the ctor (as long as that fits
215 // the lowering style). 215 // the lowering style).
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 return new (Func->allocate<InstX86FakeRMW>()) 249 return new (Func->allocate<InstX86FakeRMW>())
250 InstX86FakeRMW(Func, Data, Addr, Op, Beacon); 250 InstX86FakeRMW(Func, Data, Addr, Op, Beacon);
251 } 251 }
252 Operand *getAddr() const { return this->getSrc(1); } 252 Operand *getAddr() const { return this->getSrc(1); }
253 Operand *getData() const { return this->getSrc(0); } 253 Operand *getData() const { return this->getSrc(0); }
254 InstArithmetic::OpKind getOp() const { return Op; } 254 InstArithmetic::OpKind getOp() const { return Op; }
255 Variable *getBeacon() const { 255 Variable *getBeacon() const {
256 return llvm::cast<Variable>(this->getSrc(2)); 256 return llvm::cast<Variable>(this->getSrc(2));
257 } 257 }
258 void dump(const Cfg *Func) const override; 258 void dump(const Cfg *Func) const override;
259 static bool classof(const Inst *Inst) { 259 static bool classof(const Inst *Instr) {
260 return InstX86Base::isClassof(Inst, InstX86Base::FakeRMW); 260 return InstX86Base::isClassof(Instr, InstX86Base::FakeRMW);
261 } 261 }
262 262
263 private: 263 private:
264 InstArithmetic::OpKind Op; 264 InstArithmetic::OpKind Op;
265 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, 265 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
266 InstArithmetic::OpKind Op, Variable *Beacon); 266 InstArithmetic::OpKind Op, Variable *Beacon);
267 }; 267 };
268 268
269 class InstX86GetIP final : public InstX86Base { 269 class InstX86GetIP final : public InstX86Base {
270 InstX86GetIP() = delete; 270 InstX86GetIP() = delete;
271 InstX86GetIP(const InstX86GetIP &) = delete; 271 InstX86GetIP(const InstX86GetIP &) = delete;
272 InstX86GetIP &operator=(const InstX86GetIP &) = delete; 272 InstX86GetIP &operator=(const InstX86GetIP &) = delete;
273 273
274 public: 274 public:
275 static InstX86GetIP *create(Cfg *Func, Variable *Dest) { 275 static InstX86GetIP *create(Cfg *Func, Variable *Dest) {
276 return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest); 276 return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest);
277 } 277 }
278 void emit(const Cfg *Func) const override; 278 void emit(const Cfg *Func) const override;
279 void emitIAS(const Cfg *Func) const override; 279 void emitIAS(const Cfg *Func) const override;
280 void dump(const Cfg *Func) const override; 280 void dump(const Cfg *Func) const override;
281 static bool classof(const Inst *Inst) { 281 static bool classof(const Inst *Instr) {
282 return InstX86Base::isClassof(Inst, InstX86Base::GetIP); 282 return InstX86Base::isClassof(Instr, InstX86Base::GetIP);
283 } 283 }
284 284
285 private: 285 private:
286 InstX86GetIP(Cfg *Func, Variable *Dest); 286 InstX86GetIP(Cfg *Func, Variable *Dest);
287 }; 287 };
288 288
289 /// InstX86Label represents an intra-block label that is the target of an 289 /// InstX86Label represents an intra-block label that is the target of an
290 /// intra-block branch. The offset between the label and the branch must be 290 /// intra-block branch. The offset between the label and the branch must be
291 /// fit into one byte (considered "near"). These are used for lowering i1 291 /// fit into one byte (considered "near"). These are used for lowering i1
292 /// calculations, Select instructions, and 64-bit compares on a 32-bit 292 /// calculations, Select instructions, and 64-bit compares on a 32-bit
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 ++Sum; 405 ++Sum;
406 return Sum; 406 return Sum;
407 } 407 }
408 bool isUnconditionalBranch() const override { 408 bool isUnconditionalBranch() const override {
409 return !Label && Condition == Cond::Br_None; 409 return !Label && Condition == Cond::Br_None;
410 } 410 }
411 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; 411 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
412 void emit(const Cfg *Func) const override; 412 void emit(const Cfg *Func) const override;
413 void emitIAS(const Cfg *Func) const override; 413 void emitIAS(const Cfg *Func) const override;
414 void dump(const Cfg *Func) const override; 414 void dump(const Cfg *Func) const override;
415 static bool classof(const Inst *Inst) { 415 static bool classof(const Inst *Instr) {
416 return InstX86Base::isClassof(Inst, InstX86Base::Br); 416 return InstX86Base::isClassof(Instr, InstX86Base::Br);
417 } 417 }
418 418
419 private: 419 private:
420 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 420 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
421 const InstX86Label *Label, BrCond Condition, Mode Kind); 421 const InstX86Label *Label, BrCond Condition, Mode Kind);
422 422
423 BrCond Condition; 423 BrCond Condition;
424 const CfgNode *TargetTrue; 424 const CfgNode *TargetTrue;
425 const CfgNode *TargetFalse; 425 const CfgNode *TargetFalse;
426 const InstX86Label *Label; // Intra-block branch target 426 const InstX86Label *Label; // Intra-block branch target
427 const Mode Kind; 427 const Mode Kind;
428 }; 428 };
429 429
430 /// Jump to a target outside this function, such as tailcall, nacljump, 430 /// Jump to a target outside this function, such as tailcall, nacljump,
431 /// naclret, unreachable. This is different from a Branch instruction in that 431 /// naclret, unreachable. This is different from a Branch instruction in that
432 /// there is no intra-function control flow to represent. 432 /// there is no intra-function control flow to represent.
433 class InstX86Jmp final : public InstX86Base { 433 class InstX86Jmp final : public InstX86Base {
434 InstX86Jmp() = delete; 434 InstX86Jmp() = delete;
435 InstX86Jmp(const InstX86Jmp &) = delete; 435 InstX86Jmp(const InstX86Jmp &) = delete;
436 InstX86Jmp &operator=(const InstX86Jmp &) = delete; 436 InstX86Jmp &operator=(const InstX86Jmp &) = delete;
437 437
438 public: 438 public:
439 static InstX86Jmp *create(Cfg *Func, Operand *Target) { 439 static InstX86Jmp *create(Cfg *Func, Operand *Target) {
440 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target); 440 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
441 } 441 }
442 Operand *getJmpTarget() const { return this->getSrc(0); } 442 Operand *getJmpTarget() const { return this->getSrc(0); }
443 void emit(const Cfg *Func) const override; 443 void emit(const Cfg *Func) const override;
444 void emitIAS(const Cfg *Func) const override; 444 void emitIAS(const Cfg *Func) const override;
445 void dump(const Cfg *Func) const override; 445 void dump(const Cfg *Func) const override;
446 static bool classof(const Inst *Inst) { 446 static bool classof(const Inst *Instr) {
447 return InstX86Base::isClassof(Inst, InstX86Base::Jmp); 447 return InstX86Base::isClassof(Instr, InstX86Base::Jmp);
448 } 448 }
449 449
450 private: 450 private:
451 InstX86Jmp(Cfg *Func, Operand *Target); 451 InstX86Jmp(Cfg *Func, Operand *Target);
452 }; 452 };
453 453
454 /// Call instruction. Arguments should have already been pushed. 454 /// Call instruction. Arguments should have already been pushed.
455 class InstX86Call final : public InstX86Base { 455 class InstX86Call final : public InstX86Base {
456 InstX86Call() = delete; 456 InstX86Call() = delete;
457 InstX86Call(const InstX86Call &) = delete; 457 InstX86Call(const InstX86Call &) = delete;
458 InstX86Call &operator=(const InstX86Call &) = delete; 458 InstX86Call &operator=(const InstX86Call &) = delete;
459 459
460 public: 460 public:
461 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 461 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
462 return new (Func->allocate<InstX86Call>()) 462 return new (Func->allocate<InstX86Call>())
463 InstX86Call(Func, Dest, CallTarget); 463 InstX86Call(Func, Dest, CallTarget);
464 } 464 }
465 Operand *getCallTarget() const { return this->getSrc(0); } 465 Operand *getCallTarget() const { return this->getSrc(0); }
466 void emit(const Cfg *Func) const override; 466 void emit(const Cfg *Func) const override;
467 void emitIAS(const Cfg *Func) const override; 467 void emitIAS(const Cfg *Func) const override;
468 void dump(const Cfg *Func) const override; 468 void dump(const Cfg *Func) const override;
469 static bool classof(const Inst *Inst) { 469 static bool classof(const Inst *Instr) {
470 return InstX86Base::isClassof(Inst, InstX86Base::Call); 470 return InstX86Base::isClassof(Instr, InstX86Base::Call);
471 } 471 }
472 472
473 private: 473 private:
474 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 474 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
475 }; 475 };
476 476
477 /// Emit a one-operand (GPR) instruction. 477 /// Emit a one-operand (GPR) instruction.
478 static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 478 static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
479 const GPREmitterOneOp &Emitter); 479 const GPREmitterOneOp &Emitter);
480 480
(...skipping 29 matching lines...) Expand all
510 SReg_t (*srcEnc)(int32_t)> 510 SReg_t (*srcEnc)(int32_t)>
511 static void 511 static void
512 emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest, 512 emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest,
513 const Operand *Src0, const Operand *Src1, 513 const Operand *Src0, const Operand *Src1,
514 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter); 514 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter);
515 515
516 static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, 516 static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
517 const Operand *Src, 517 const Operand *Src,
518 const XmmEmitterMovOps Emitter); 518 const XmmEmitterMovOps Emitter);
519 519
520 static void emitVariableBlendInst(const char *Opcode, const Inst *Inst, 520 static void emitVariableBlendInst(const char *Opcode, const Inst *Instr,
521 const Cfg *Func); 521 const Cfg *Func);
522 522
523 static void emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, 523 static void emitIASVariableBlendInst(const Inst *Instr, const Cfg *Func,
524 const XmmEmitterRegOp &Emitter); 524 const XmmEmitterRegOp &Emitter);
525 525
526 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 526 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
527 const Operand *Src, 527 const Operand *Src,
528 const XmmEmitterShiftOp &Emitter); 528 const XmmEmitterShiftOp &Emitter);
529 529
530 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable 530 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable
531 /// that's guaranteed to be a register. 531 /// that's guaranteed to be a register.
532 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> 532 template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
533 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty, 533 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty,
(...skipping 26 matching lines...) Expand all
560 emitIASOpTyGPR(Func, Ty, Var, Emitter); 560 emitIASOpTyGPR(Func, Ty, Var, Emitter);
561 } 561 }
562 void dump(const Cfg *Func) const override { 562 void dump(const Cfg *Func) const override {
563 if (!BuildDefs::dump()) 563 if (!BuildDefs::dump())
564 return; 564 return;
565 Ostream &Str = Func->getContext()->getStrDump(); 565 Ostream &Str = Func->getContext()->getStrDump();
566 this->dumpDest(Func); 566 this->dumpDest(Func);
567 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 567 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
568 this->dumpSources(Func); 568 this->dumpSources(Func);
569 } 569 }
570 static bool classof(const Inst *Inst) { 570 static bool classof(const Inst *Instr) {
571 return InstX86Base::isClassof(Inst, InstX86Base::K); 571 return InstX86Base::isClassof(Instr, InstX86Base::K);
572 } 572 }
573 573
574 protected: 574 protected:
575 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest) 575 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest)
576 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 576 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
577 this->addSource(SrcDest); 577 this->addSource(SrcDest);
578 } 578 }
579 579
580 private: 580 private:
581 static const char *Opcode; 581 static const char *Opcode;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter); 619 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter);
620 } 620 }
621 void dump(const Cfg *Func) const override { 621 void dump(const Cfg *Func) const override {
622 if (!BuildDefs::dump()) 622 if (!BuildDefs::dump())
623 return; 623 return;
624 Ostream &Str = Func->getContext()->getStrDump(); 624 Ostream &Str = Func->getContext()->getStrDump();
625 this->dumpDest(Func); 625 this->dumpDest(Func);
626 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; 626 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " ";
627 this->dumpSources(Func); 627 this->dumpSources(Func);
628 } 628 }
629 static bool classof(const Inst *Inst) { 629 static bool classof(const Inst *Instr) {
630 return InstX86Base::isClassof(Inst, InstX86Base::K); 630 return InstX86Base::isClassof(Instr, InstX86Base::K);
631 } 631 }
632 632
633 protected: 633 protected:
634 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) 634 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
635 : InstX86Base(Func, K, 1, Dest) { 635 : InstX86Base(Func, K, 1, Dest) {
636 this->addSource(Src); 636 this->addSource(Src);
637 } 637 }
638 638
639 static const char *Opcode; 639 static const char *Opcode;
640 static const GPREmitterRegOp Emitter; 640 static const GPREmitterRegOp Emitter;
(...skipping 24 matching lines...) Expand all
665 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter); 665 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter);
666 } 666 }
667 void dump(const Cfg *Func) const override { 667 void dump(const Cfg *Func) const override {
668 if (!BuildDefs::dump()) 668 if (!BuildDefs::dump())
669 return; 669 return;
670 Ostream &Str = Func->getContext()->getStrDump(); 670 Ostream &Str = Func->getContext()->getStrDump();
671 this->dumpDest(Func); 671 this->dumpDest(Func);
672 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 672 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
673 this->dumpSources(Func); 673 this->dumpSources(Func);
674 } 674 }
675 static bool classof(const Inst *Inst) { 675 static bool classof(const Inst *Instr) {
676 return InstX86Base::isClassof(Inst, InstX86Base::K); 676 return InstX86Base::isClassof(Instr, InstX86Base::K);
677 } 677 }
678 678
679 protected: 679 protected:
680 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) 680 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
681 : InstX86Base(Func, K, 1, Dest) { 681 : InstX86Base(Func, K, 1, Dest) {
682 this->addSource(Src); 682 this->addSource(Src);
683 } 683 }
684 684
685 static const char *Opcode; 685 static const char *Opcode;
686 static const XmmEmitterRegOp Emitter; 686 static const XmmEmitterRegOp Emitter;
(...skipping 20 matching lines...) Expand all
707 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter); 707 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
708 } 708 }
709 void dump(const Cfg *Func) const override { 709 void dump(const Cfg *Func) const override {
710 if (!BuildDefs::dump()) 710 if (!BuildDefs::dump())
711 return; 711 return;
712 Ostream &Str = Func->getContext()->getStrDump(); 712 Ostream &Str = Func->getContext()->getStrDump();
713 this->dumpDest(Func); 713 this->dumpDest(Func);
714 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 714 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
715 this->dumpSources(Func); 715 this->dumpSources(Func);
716 } 716 }
717 static bool classof(const Inst *Inst) { 717 static bool classof(const Inst *Instr) {
718 return InstX86Base::isClassof(Inst, InstX86Base::K); 718 return InstX86Base::isClassof(Instr, InstX86Base::K);
719 } 719 }
720 720
721 protected: 721 protected:
722 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) 722 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
723 : InstX86Base(Func, K, 2, Dest) { 723 : InstX86Base(Func, K, 2, Dest) {
724 this->addSource(Dest); 724 this->addSource(Dest);
725 this->addSource(Source); 725 this->addSource(Source);
726 } 726 }
727 727
728 static const char *Opcode; 728 static const char *Opcode;
(...skipping 23 matching lines...) Expand all
752 Emitter); 752 Emitter);
753 } 753 }
754 void dump(const Cfg *Func) const override { 754 void dump(const Cfg *Func) const override {
755 if (!BuildDefs::dump()) 755 if (!BuildDefs::dump())
756 return; 756 return;
757 Ostream &Str = Func->getContext()->getStrDump(); 757 Ostream &Str = Func->getContext()->getStrDump();
758 this->dumpDest(Func); 758 this->dumpDest(Func);
759 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 759 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
760 this->dumpSources(Func); 760 this->dumpSources(Func);
761 } 761 }
762 static bool classof(const Inst *Inst) { 762 static bool classof(const Inst *Instr) {
763 return InstX86Base::isClassof(Inst, InstX86Base::K); 763 return InstX86Base::isClassof(Instr, InstX86Base::K);
764 } 764 }
765 765
766 protected: 766 protected:
767 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source) 767 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
768 : InstX86Base(Func, K, 2, Dest) { 768 : InstX86Base(Func, K, 2, Dest) {
769 this->addSource(Dest); 769 this->addSource(Dest);
770 this->addSource(Source); 770 this->addSource(Source);
771 } 771 }
772 772
773 static const char *Opcode; 773 static const char *Opcode;
(...skipping 19 matching lines...) Expand all
793 assert(this->getSrcSize() == 2); 793 assert(this->getSrcSize() == 2);
794 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter); 794 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter);
795 } 795 }
796 void dump(const Cfg *Func) const override { 796 void dump(const Cfg *Func) const override {
797 if (!BuildDefs::dump()) 797 if (!BuildDefs::dump())
798 return; 798 return;
799 Ostream &Str = Func->getContext()->getStrDump(); 799 Ostream &Str = Func->getContext()->getStrDump();
800 Str << Opcode << "." << this->getSrc(0)->getType() << " "; 800 Str << Opcode << "." << this->getSrc(0)->getType() << " ";
801 this->dumpSources(Func); 801 this->dumpSources(Func);
802 } 802 }
803 static bool classof(const Inst *Inst) { 803 static bool classof(const Inst *Instr) {
804 return InstX86Base::isClassof(Inst, InstX86Base::K); 804 return InstX86Base::isClassof(Instr, InstX86Base::K);
805 } 805 }
806 806
807 protected: 807 protected:
808 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) 808 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
809 : InstX86Base(Func, K, 2, nullptr) { 809 : InstX86Base(Func, K, 2, nullptr) {
810 this->addSource(DestSrc0); 810 this->addSource(DestSrc0);
811 this->addSource(Src1); 811 this->addSource(Src1);
812 } 812 }
813 813
814 static const char *Opcode; 814 static const char *Opcode;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter); 857 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
858 } 858 }
859 void dump(const Cfg *Func) const override { 859 void dump(const Cfg *Func) const override {
860 if (!BuildDefs::dump()) 860 if (!BuildDefs::dump())
861 return; 861 return;
862 Ostream &Str = Func->getContext()->getStrDump(); 862 Ostream &Str = Func->getContext()->getStrDump();
863 this->dumpDest(Func); 863 this->dumpDest(Func);
864 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 864 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
865 this->dumpSources(Func); 865 this->dumpSources(Func);
866 } 866 }
867 static bool classof(const Inst *Inst) { 867 static bool classof(const Inst *Instr) {
868 return InstX86Base::isClassof(Inst, InstX86Base::K); 868 return InstX86Base::isClassof(Instr, InstX86Base::K);
869 } 869 }
870 870
871 protected: 871 protected:
872 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source, 872 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source,
873 Type ArithmeticTypeOverride = IceType_void) 873 Type ArithmeticTypeOverride = IceType_void)
874 : InstX86Base(Func, K, 2, Dest), 874 : InstX86Base(Func, K, 2, Dest),
875 ArithmeticTypeOverride(ArithmeticTypeOverride) { 875 ArithmeticTypeOverride(ArithmeticTypeOverride) {
876 this->addSource(Dest); 876 this->addSource(Dest);
877 this->addSource(Source); 877 this->addSource(Source);
878 } 878 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 Emitter); 911 Emitter);
912 } 912 }
913 void dump(const Cfg *Func) const override { 913 void dump(const Cfg *Func) const override {
914 if (!BuildDefs::dump()) 914 if (!BuildDefs::dump())
915 return; 915 return;
916 Ostream &Str = Func->getContext()->getStrDump(); 916 Ostream &Str = Func->getContext()->getStrDump();
917 this->dumpDest(Func); 917 this->dumpDest(Func);
918 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 918 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
919 this->dumpSources(Func); 919 this->dumpSources(Func);
920 } 920 }
921 static bool classof(const Inst *Inst) { 921 static bool classof(const Inst *Instr) {
922 return InstX86Base::isClassof(Inst, InstX86Base::K); 922 return InstX86Base::isClassof(Instr, InstX86Base::K);
923 } 923 }
924 924
925 protected: 925 protected:
926 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) 926 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
927 : InstX86Base(Func, K, 2, Dest) { 927 : InstX86Base(Func, K, 2, Dest) {
928 this->addSource(Dest); 928 this->addSource(Dest);
929 this->addSource(Source); 929 this->addSource(Source);
930 } 930 }
931 931
932 static const char *Opcode; 932 static const char *Opcode;
(...skipping 22 matching lines...) Expand all
955 this->getDest()->emit(Func); 955 this->getDest()->emit(Func);
956 } 956 }
957 void dump(const Cfg *Func) const override { 957 void dump(const Cfg *Func) const override {
958 if (!BuildDefs::dump()) 958 if (!BuildDefs::dump())
959 return; 959 return;
960 Ostream &Str = Func->getContext()->getStrDump(); 960 Ostream &Str = Func->getContext()->getStrDump();
961 this->dumpDest(Func); 961 this->dumpDest(Func);
962 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 962 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
963 this->dumpSources(Func); 963 this->dumpSources(Func);
964 } 964 }
965 static bool classof(const Inst *Inst) { 965 static bool classof(const Inst *Instr) {
966 return InstX86Base::isClassof(Inst, InstX86Base::K); 966 return InstX86Base::isClassof(Instr, InstX86Base::K);
967 } 967 }
968 968
969 protected: 969 protected:
970 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1, 970 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1,
971 Operand *Source2) 971 Operand *Source2)
972 : InstX86Base(Func, K, 3, Dest) { 972 : InstX86Base(Func, K, 3, Dest) {
973 this->addSource(Dest); 973 this->addSource(Dest);
974 this->addSource(Source1); 974 this->addSource(Source1);
975 this->addSource(Source2); 975 this->addSource(Source2);
976 } 976 }
(...skipping 25 matching lines...) Expand all
1002 this->getDest()->emit(Func); 1002 this->getDest()->emit(Func);
1003 } 1003 }
1004 void dump(const Cfg *Func) const override { 1004 void dump(const Cfg *Func) const override {
1005 if (!BuildDefs::dump()) 1005 if (!BuildDefs::dump())
1006 return; 1006 return;
1007 Ostream &Str = Func->getContext()->getStrDump(); 1007 Ostream &Str = Func->getContext()->getStrDump();
1008 this->dumpDest(Func); 1008 this->dumpDest(Func);
1009 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; 1009 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
1010 this->dumpSources(Func); 1010 this->dumpSources(Func);
1011 } 1011 }
1012 static bool classof(const Inst *Inst) { 1012 static bool classof(const Inst *Instr) {
1013 return InstX86Base::isClassof(Inst, InstX86Base::K); 1013 return InstX86Base::isClassof(Instr, InstX86Base::K);
1014 } 1014 }
1015 1015
1016 protected: 1016 protected:
1017 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, 1017 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
1018 Operand *Source1) 1018 Operand *Source1)
1019 : InstX86Base(Func, K, 2, Dest) { 1019 : InstX86Base(Func, K, 2, Dest) {
1020 this->addSource(Source0); 1020 this->addSource(Source0);
1021 this->addSource(Source1); 1021 this->addSource(Source1);
1022 } 1022 }
1023 1023
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 } 1059 }
1060 void dump(const Cfg *Func) const override { 1060 void dump(const Cfg *Func) const override {
1061 if (!BuildDefs::dump()) 1061 if (!BuildDefs::dump())
1062 return; 1062 return;
1063 Ostream &Str = Func->getContext()->getStrDump(); 1063 Ostream &Str = Func->getContext()->getStrDump();
1064 Str << Opcode << "." << this->getDest()->getType() << " "; 1064 Str << Opcode << "." << this->getDest()->getType() << " ";
1065 this->dumpDest(Func); 1065 this->dumpDest(Func);
1066 Str << ", "; 1066 Str << ", ";
1067 this->dumpSources(Func); 1067 this->dumpSources(Func);
1068 } 1068 }
1069 static bool classof(const Inst *Inst) { 1069 static bool classof(const Inst *Instr) {
1070 return InstX86Base::isClassof(Inst, InstX86Base::K); 1070 return InstX86Base::isClassof(Instr, InstX86Base::K);
1071 } 1071 }
1072 1072
1073 protected: 1073 protected:
1074 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source) 1074 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source)
1075 : InstX86Base(Func, K, 1, Dest) { 1075 : InstX86Base(Func, K, 1, Dest) {
1076 this->addSource(Source); 1076 this->addSource(Source);
1077 // For an integer assignment, make sure it's either a same-type assignment 1077 // For an integer assignment, make sure it's either a same-type assignment
1078 // or a truncation. 1078 // or a truncation.
1079 assert(!isScalarIntegerType(Dest->getType()) || 1079 assert(!isScalarIntegerType(Dest->getType()) ||
1080 (typeWidthInBytes(Dest->getType()) <= 1080 (typeWidthInBytes(Dest->getType()) <=
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 2180
2181 public: 2181 public:
2182 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 2182 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
2183 Operand *Source2) { 2183 Operand *Source2) {
2184 return new (Func->allocate<InstX86Mul>()) 2184 return new (Func->allocate<InstX86Mul>())
2185 InstX86Mul(Func, Dest, Source1, Source2); 2185 InstX86Mul(Func, Dest, Source1, Source2);
2186 } 2186 }
2187 void emit(const Cfg *Func) const override; 2187 void emit(const Cfg *Func) const override;
2188 void emitIAS(const Cfg *Func) const override; 2188 void emitIAS(const Cfg *Func) const override;
2189 void dump(const Cfg *Func) const override; 2189 void dump(const Cfg *Func) const override;
2190 static bool classof(const Inst *Inst) { 2190 static bool classof(const Inst *Instr) {
2191 return InstX86Base::isClassof(Inst, InstX86Base::Mul); 2191 return InstX86Base::isClassof(Instr, InstX86Base::Mul);
2192 } 2192 }
2193 2193
2194 private: 2194 private:
2195 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2195 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2196 }; 2196 };
2197 2197
2198 /// Shld instruction - shift across a pair of operands. 2198 /// Shld instruction - shift across a pair of operands.
2199 class InstX86Shld final : public InstX86Base { 2199 class InstX86Shld final : public InstX86Base {
2200 InstX86Shld() = delete; 2200 InstX86Shld() = delete;
2201 InstX86Shld(const InstX86Shld &) = delete; 2201 InstX86Shld(const InstX86Shld &) = delete;
2202 InstX86Shld &operator=(const InstX86Shld &) = delete; 2202 InstX86Shld &operator=(const InstX86Shld &) = delete;
2203 2203
2204 public: 2204 public:
2205 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 2205 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
2206 Operand *Source2) { 2206 Operand *Source2) {
2207 return new (Func->allocate<InstX86Shld>()) 2207 return new (Func->allocate<InstX86Shld>())
2208 InstX86Shld(Func, Dest, Source1, Source2); 2208 InstX86Shld(Func, Dest, Source1, Source2);
2209 } 2209 }
2210 void emit(const Cfg *Func) const override; 2210 void emit(const Cfg *Func) const override;
2211 void emitIAS(const Cfg *Func) const override; 2211 void emitIAS(const Cfg *Func) const override;
2212 void dump(const Cfg *Func) const override; 2212 void dump(const Cfg *Func) const override;
2213 static bool classof(const Inst *Inst) { 2213 static bool classof(const Inst *Instr) {
2214 return InstX86Base::isClassof(Inst, InstX86Base::Shld); 2214 return InstX86Base::isClassof(Instr, InstX86Base::Shld);
2215 } 2215 }
2216 2216
2217 private: 2217 private:
2218 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2218 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2219 }; 2219 };
2220 2220
2221 /// Shrd instruction - shift across a pair of operands. 2221 /// Shrd instruction - shift across a pair of operands.
2222 class InstX86Shrd final : public InstX86Base { 2222 class InstX86Shrd final : public InstX86Base {
2223 InstX86Shrd() = delete; 2223 InstX86Shrd() = delete;
2224 InstX86Shrd(const InstX86Shrd &) = delete; 2224 InstX86Shrd(const InstX86Shrd &) = delete;
2225 InstX86Shrd &operator=(const InstX86Shrd &) = delete; 2225 InstX86Shrd &operator=(const InstX86Shrd &) = delete;
2226 2226
2227 public: 2227 public:
2228 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 2228 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
2229 Operand *Source2) { 2229 Operand *Source2) {
2230 return new (Func->allocate<InstX86Shrd>()) 2230 return new (Func->allocate<InstX86Shrd>())
2231 InstX86Shrd(Func, Dest, Source1, Source2); 2231 InstX86Shrd(Func, Dest, Source1, Source2);
2232 } 2232 }
2233 void emit(const Cfg *Func) const override; 2233 void emit(const Cfg *Func) const override;
2234 void emitIAS(const Cfg *Func) const override; 2234 void emitIAS(const Cfg *Func) const override;
2235 void dump(const Cfg *Func) const override; 2235 void dump(const Cfg *Func) const override;
2236 static bool classof(const Inst *Inst) { 2236 static bool classof(const Inst *Instr) {
2237 return InstX86Base::isClassof(Inst, InstX86Base::Shrd); 2237 return InstX86Base::isClassof(Instr, InstX86Base::Shrd);
2238 } 2238 }
2239 2239
2240 private: 2240 private:
2241 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 2241 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2242 }; 2242 };
2243 2243
2244 /// Conditional move instruction. 2244 /// Conditional move instruction.
2245 class InstX86Cmov final : public InstX86Base { 2245 class InstX86Cmov final : public InstX86Base {
2246 InstX86Cmov() = delete; 2246 InstX86Cmov() = delete;
2247 InstX86Cmov(const InstX86Cmov &) = delete; 2247 InstX86Cmov(const InstX86Cmov &) = delete;
2248 InstX86Cmov &operator=(const InstX86Cmov &) = delete; 2248 InstX86Cmov &operator=(const InstX86Cmov &) = delete;
2249 2249
2250 public: 2250 public:
2251 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 2251 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
2252 BrCond Cond) { 2252 BrCond Cond) {
2253 return new (Func->allocate<InstX86Cmov>()) 2253 return new (Func->allocate<InstX86Cmov>())
2254 InstX86Cmov(Func, Dest, Source, Cond); 2254 InstX86Cmov(Func, Dest, Source, Cond);
2255 } 2255 }
2256 void emit(const Cfg *Func) const override; 2256 void emit(const Cfg *Func) const override;
2257 void emitIAS(const Cfg *Func) const override; 2257 void emitIAS(const Cfg *Func) const override;
2258 void dump(const Cfg *Func) const override; 2258 void dump(const Cfg *Func) const override;
2259 static bool classof(const Inst *Inst) { 2259 static bool classof(const Inst *Instr) {
2260 return InstX86Base::isClassof(Inst, InstX86Base::Cmov); 2260 return InstX86Base::isClassof(Instr, InstX86Base::Cmov);
2261 } 2261 }
2262 2262
2263 private: 2263 private:
2264 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond); 2264 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond);
2265 2265
2266 BrCond Condition; 2266 BrCond Condition;
2267 }; 2267 };
2268 2268
2269 /// Cmpps instruction - compare packed singled-precision floating point values 2269 /// Cmpps instruction - compare packed singled-precision floating point values
2270 class InstX86Cmpps final : public InstX86Base { 2270 class InstX86Cmpps final : public InstX86Base {
2271 InstX86Cmpps() = delete; 2271 InstX86Cmpps() = delete;
2272 InstX86Cmpps(const InstX86Cmpps &) = delete; 2272 InstX86Cmpps(const InstX86Cmpps &) = delete;
2273 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete; 2273 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete;
2274 2274
2275 public: 2275 public:
2276 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 2276 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
2277 CmppsCond Condition) { 2277 CmppsCond Condition) {
2278 return new (Func->allocate<InstX86Cmpps>()) 2278 return new (Func->allocate<InstX86Cmpps>())
2279 InstX86Cmpps(Func, Dest, Source, Condition); 2279 InstX86Cmpps(Func, Dest, Source, Condition);
2280 } 2280 }
2281 void emit(const Cfg *Func) const override; 2281 void emit(const Cfg *Func) const override;
2282 void emitIAS(const Cfg *Func) const override; 2282 void emitIAS(const Cfg *Func) const override;
2283 void dump(const Cfg *Func) const override; 2283 void dump(const Cfg *Func) const override;
2284 static bool classof(const Inst *Inst) { 2284 static bool classof(const Inst *Instr) {
2285 return InstX86Base::isClassof(Inst, InstX86Base::Cmpps); 2285 return InstX86Base::isClassof(Instr, InstX86Base::Cmpps);
2286 } 2286 }
2287 2287
2288 private: 2288 private:
2289 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond); 2289 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond);
2290 2290
2291 CmppsCond Condition; 2291 CmppsCond Condition;
2292 }; 2292 };
2293 2293
2294 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 2294 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
2295 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If 2295 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If
2296 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest> 2296 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest>
2297 /// can be a register or memory, while <desired> must be a register. It is 2297 /// can be a register or memory, while <desired> must be a register. It is
2298 /// the user's responsibility to mark eax with a FakeDef. 2298 /// the user's responsibility to mark eax with a FakeDef.
2299 class InstX86Cmpxchg final : public InstX86BaseLockable { 2299 class InstX86Cmpxchg final : public InstX86BaseLockable {
2300 InstX86Cmpxchg() = delete; 2300 InstX86Cmpxchg() = delete;
2301 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete; 2301 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete;
2302 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete; 2302 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete;
2303 2303
2304 public: 2304 public:
2305 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2305 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2306 Variable *Desired, bool Locked) { 2306 Variable *Desired, bool Locked) {
2307 return new (Func->allocate<InstX86Cmpxchg>()) 2307 return new (Func->allocate<InstX86Cmpxchg>())
2308 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 2308 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
2309 } 2309 }
2310 void emit(const Cfg *Func) const override; 2310 void emit(const Cfg *Func) const override;
2311 void emitIAS(const Cfg *Func) const override; 2311 void emitIAS(const Cfg *Func) const override;
2312 void dump(const Cfg *Func) const override; 2312 void dump(const Cfg *Func) const override;
2313 static bool classof(const Inst *Inst) { 2313 static bool classof(const Inst *Instr) {
2314 return InstX86Base::isClassof(Inst, InstX86Base::Cmpxchg); 2314 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg);
2315 } 2315 }
2316 2316
2317 private: 2317 private:
2318 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2318 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2319 Variable *Desired, bool Locked); 2319 Variable *Desired, bool Locked);
2320 }; 2320 };
2321 2321
2322 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals 2322 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals
2323 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF 2323 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF
2324 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for 2324 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for
2325 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory 2325 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory
2326 /// operand. 2326 /// operand.
2327 class InstX86Cmpxchg8b final : public InstX86BaseLockable { 2327 class InstX86Cmpxchg8b final : public InstX86BaseLockable {
2328 InstX86Cmpxchg8b() = delete; 2328 InstX86Cmpxchg8b() = delete;
2329 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete; 2329 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete;
2330 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete; 2330 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete;
2331 2331
2332 public: 2332 public:
2333 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest, 2333 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest,
2334 Variable *Edx, Variable *Eax, Variable *Ecx, 2334 Variable *Edx, Variable *Eax, Variable *Ecx,
2335 Variable *Ebx, bool Locked) { 2335 Variable *Ebx, bool Locked) {
2336 return new (Func->allocate<InstX86Cmpxchg8b>()) 2336 return new (Func->allocate<InstX86Cmpxchg8b>())
2337 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 2337 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
2338 } 2338 }
2339 void emit(const Cfg *Func) const override; 2339 void emit(const Cfg *Func) const override;
2340 void emitIAS(const Cfg *Func) const override; 2340 void emitIAS(const Cfg *Func) const override;
2341 void dump(const Cfg *Func) const override; 2341 void dump(const Cfg *Func) const override;
2342 static bool classof(const Inst *Inst) { 2342 static bool classof(const Inst *Instr) {
2343 return InstX86Base::isClassof(Inst, InstX86Base::Cmpxchg8b); 2343 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg8b);
2344 } 2344 }
2345 2345
2346 private: 2346 private:
2347 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx, 2347 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx,
2348 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); 2348 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
2349 }; 2349 };
2350 2350
2351 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as 2351 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as
2352 /// appropriate. s=float, d=double, i=int. X and Y are determined from 2352 /// appropriate. s=float, d=double, i=int. X and Y are determined from
2353 /// dest/src types. Sign and zero extension on the integer operand needs to be 2353 /// dest/src types. Sign and zero extension on the integer operand needs to be
2354 /// done separately. 2354 /// done separately.
2355 class InstX86Cvt final : public InstX86Base { 2355 class InstX86Cvt final : public InstX86Base {
2356 InstX86Cvt() = delete; 2356 InstX86Cvt() = delete;
2357 InstX86Cvt(const InstX86Cvt &) = delete; 2357 InstX86Cvt(const InstX86Cvt &) = delete;
2358 InstX86Cvt &operator=(const InstX86Cvt &) = delete; 2358 InstX86Cvt &operator=(const InstX86Cvt &) = delete;
2359 2359
2360 public: 2360 public:
2361 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 2361 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
2362 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 2362 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
2363 CvtVariant Variant) { 2363 CvtVariant Variant) {
2364 return new (Func->allocate<InstX86Cvt>()) 2364 return new (Func->allocate<InstX86Cvt>())
2365 InstX86Cvt(Func, Dest, Source, Variant); 2365 InstX86Cvt(Func, Dest, Source, Variant);
2366 } 2366 }
2367 void emit(const Cfg *Func) const override; 2367 void emit(const Cfg *Func) const override;
2368 void emitIAS(const Cfg *Func) const override; 2368 void emitIAS(const Cfg *Func) const override;
2369 void dump(const Cfg *Func) const override; 2369 void dump(const Cfg *Func) const override;
2370 static bool classof(const Inst *Inst) { 2370 static bool classof(const Inst *Instr) {
2371 return InstX86Base::isClassof(Inst, InstX86Base::Cvt); 2371 return InstX86Base::isClassof(Instr, InstX86Base::Cvt);
2372 } 2372 }
2373 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 2373 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
2374 2374
2375 private: 2375 private:
2376 CvtVariant Variant; 2376 CvtVariant Variant;
2377 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 2377 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
2378 }; 2378 };
2379 2379
2380 /// cmp - Integer compare instruction. 2380 /// cmp - Integer compare instruction.
2381 class InstX86Icmp final : public InstX86Base { 2381 class InstX86Icmp final : public InstX86Base {
2382 InstX86Icmp() = delete; 2382 InstX86Icmp() = delete;
2383 InstX86Icmp(const InstX86Icmp &) = delete; 2383 InstX86Icmp(const InstX86Icmp &) = delete;
2384 InstX86Icmp &operator=(const InstX86Icmp &) = delete; 2384 InstX86Icmp &operator=(const InstX86Icmp &) = delete;
2385 2385
2386 public: 2386 public:
2387 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 2387 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2388 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2); 2388 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2);
2389 } 2389 }
2390 void emit(const Cfg *Func) const override; 2390 void emit(const Cfg *Func) const override;
2391 void emitIAS(const Cfg *Func) const override; 2391 void emitIAS(const Cfg *Func) const override;
2392 void dump(const Cfg *Func) const override; 2392 void dump(const Cfg *Func) const override;
2393 static bool classof(const Inst *Inst) { 2393 static bool classof(const Inst *Instr) {
2394 return InstX86Base::isClassof(Inst, InstX86Base::Icmp); 2394 return InstX86Base::isClassof(Instr, InstX86Base::Icmp);
2395 } 2395 }
2396 2396
2397 private: 2397 private:
2398 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 2398 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
2399 }; 2399 };
2400 2400
2401 /// ucomiss/ucomisd - floating-point compare instruction. 2401 /// ucomiss/ucomisd - floating-point compare instruction.
2402 class InstX86Ucomiss final : public InstX86Base { 2402 class InstX86Ucomiss final : public InstX86Base {
2403 InstX86Ucomiss() = delete; 2403 InstX86Ucomiss() = delete;
2404 InstX86Ucomiss(const InstX86Ucomiss &) = delete; 2404 InstX86Ucomiss(const InstX86Ucomiss &) = delete;
2405 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete; 2405 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete;
2406 2406
2407 public: 2407 public:
2408 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 2408 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2409 return new (Func->allocate<InstX86Ucomiss>()) 2409 return new (Func->allocate<InstX86Ucomiss>())
2410 InstX86Ucomiss(Func, Src1, Src2); 2410 InstX86Ucomiss(Func, Src1, Src2);
2411 } 2411 }
2412 void emit(const Cfg *Func) const override; 2412 void emit(const Cfg *Func) const override;
2413 void emitIAS(const Cfg *Func) const override; 2413 void emitIAS(const Cfg *Func) const override;
2414 void dump(const Cfg *Func) const override; 2414 void dump(const Cfg *Func) const override;
2415 static bool classof(const Inst *Inst) { 2415 static bool classof(const Inst *Instr) {
2416 return InstX86Base::isClassof(Inst, InstX86Base::Ucomiss); 2416 return InstX86Base::isClassof(Instr, InstX86Base::Ucomiss);
2417 } 2417 }
2418 2418
2419 private: 2419 private:
2420 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 2420 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
2421 }; 2421 };
2422 2422
2423 /// UD2 instruction. 2423 /// UD2 instruction.
2424 class InstX86UD2 final : public InstX86Base { 2424 class InstX86UD2 final : public InstX86Base {
2425 InstX86UD2() = delete; 2425 InstX86UD2() = delete;
2426 InstX86UD2(const InstX86UD2 &) = delete; 2426 InstX86UD2(const InstX86UD2 &) = delete;
2427 InstX86UD2 &operator=(const InstX86UD2 &) = delete; 2427 InstX86UD2 &operator=(const InstX86UD2 &) = delete;
2428 2428
2429 public: 2429 public:
2430 static InstX86UD2 *create(Cfg *Func) { 2430 static InstX86UD2 *create(Cfg *Func) {
2431 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func); 2431 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func);
2432 } 2432 }
2433 void emit(const Cfg *Func) const override; 2433 void emit(const Cfg *Func) const override;
2434 void emitIAS(const Cfg *Func) const override; 2434 void emitIAS(const Cfg *Func) const override;
2435 void dump(const Cfg *Func) const override; 2435 void dump(const Cfg *Func) const override;
2436 static bool classof(const Inst *Inst) { 2436 static bool classof(const Inst *Instr) {
2437 return InstX86Base::isClassof(Inst, InstX86Base::UD2); 2437 return InstX86Base::isClassof(Instr, InstX86Base::UD2);
2438 } 2438 }
2439 2439
2440 private: 2440 private:
2441 explicit InstX86UD2(Cfg *Func); 2441 explicit InstX86UD2(Cfg *Func);
2442 }; 2442 };
2443 2443
2444 /// Test instruction. 2444 /// Test instruction.
2445 class InstX86Test final : public InstX86Base { 2445 class InstX86Test final : public InstX86Base {
2446 InstX86Test() = delete; 2446 InstX86Test() = delete;
2447 InstX86Test(const InstX86Test &) = delete; 2447 InstX86Test(const InstX86Test &) = delete;
2448 InstX86Test &operator=(const InstX86Test &) = delete; 2448 InstX86Test &operator=(const InstX86Test &) = delete;
2449 2449
2450 public: 2450 public:
2451 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 2451 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
2452 return new (Func->allocate<InstX86Test>()) 2452 return new (Func->allocate<InstX86Test>())
2453 InstX86Test(Func, Source1, Source2); 2453 InstX86Test(Func, Source1, Source2);
2454 } 2454 }
2455 void emit(const Cfg *Func) const override; 2455 void emit(const Cfg *Func) const override;
2456 void emitIAS(const Cfg *Func) const override; 2456 void emitIAS(const Cfg *Func) const override;
2457 void dump(const Cfg *Func) const override; 2457 void dump(const Cfg *Func) const override;
2458 static bool classof(const Inst *Inst) { 2458 static bool classof(const Inst *Instr) {
2459 return InstX86Base::isClassof(Inst, InstX86Base::Test); 2459 return InstX86Base::isClassof(Instr, InstX86Base::Test);
2460 } 2460 }
2461 2461
2462 private: 2462 private:
2463 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2); 2463 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2);
2464 }; 2464 };
2465 2465
2466 /// Mfence instruction. 2466 /// Mfence instruction.
2467 class InstX86Mfence final : public InstX86Base { 2467 class InstX86Mfence final : public InstX86Base {
2468 InstX86Mfence() = delete; 2468 InstX86Mfence() = delete;
2469 InstX86Mfence(const InstX86Mfence &) = delete; 2469 InstX86Mfence(const InstX86Mfence &) = delete;
2470 InstX86Mfence &operator=(const InstX86Mfence &) = delete; 2470 InstX86Mfence &operator=(const InstX86Mfence &) = delete;
2471 2471
2472 public: 2472 public:
2473 static InstX86Mfence *create(Cfg *Func) { 2473 static InstX86Mfence *create(Cfg *Func) {
2474 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func); 2474 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func);
2475 } 2475 }
2476 void emit(const Cfg *Func) const override; 2476 void emit(const Cfg *Func) const override;
2477 void emitIAS(const Cfg *Func) const override; 2477 void emitIAS(const Cfg *Func) const override;
2478 void dump(const Cfg *Func) const override; 2478 void dump(const Cfg *Func) const override;
2479 static bool classof(const Inst *Inst) { 2479 static bool classof(const Inst *Instr) {
2480 return InstX86Base::isClassof(Inst, InstX86Base::Mfence); 2480 return InstX86Base::isClassof(Instr, InstX86Base::Mfence);
2481 } 2481 }
2482 2482
2483 private: 2483 private:
2484 explicit InstX86Mfence(Cfg *Func); 2484 explicit InstX86Mfence(Cfg *Func);
2485 }; 2485 };
2486 2486
2487 /// This is essentially a "mov" instruction with anX86OperandMem operand 2487 /// This is essentially a "mov" instruction with anX86OperandMem operand
2488 /// instead of Variable as the destination. It's important for liveness that 2488 /// instead of Variable as the destination. It's important for liveness that
2489 /// there is no Dest operand. 2489 /// there is no Dest operand.
2490 class InstX86Store final : public InstX86Base { 2490 class InstX86Store final : public InstX86Base {
2491 InstX86Store() = delete; 2491 InstX86Store() = delete;
2492 InstX86Store(const InstX86Store &) = delete; 2492 InstX86Store(const InstX86Store &) = delete;
2493 InstX86Store &operator=(const InstX86Store &) = delete; 2493 InstX86Store &operator=(const InstX86Store &) = delete;
2494 2494
2495 public: 2495 public:
2496 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) { 2496 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) {
2497 return new (Func->allocate<InstX86Store>()) 2497 return new (Func->allocate<InstX86Store>())
2498 InstX86Store(Func, Value, Mem); 2498 InstX86Store(Func, Value, Mem);
2499 } 2499 }
2500 void emit(const Cfg *Func) const override; 2500 void emit(const Cfg *Func) const override;
2501 void emitIAS(const Cfg *Func) const override; 2501 void emitIAS(const Cfg *Func) const override;
2502 void dump(const Cfg *Func) const override; 2502 void dump(const Cfg *Func) const override;
2503 static bool classof(const Inst *Inst) { 2503 static bool classof(const Inst *Instr) {
2504 return InstX86Base::isClassof(Inst, InstX86Base::Store); 2504 return InstX86Base::isClassof(Instr, InstX86Base::Store);
2505 } 2505 }
2506 2506
2507 private: 2507 private:
2508 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem); 2508 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem);
2509 }; 2509 };
2510 2510
2511 /// This is essentially a vector "mov" instruction with an typename 2511 /// This is essentially a vector "mov" instruction with an typename
2512 /// X86OperandMem operand instead of Variable as the destination. It's 2512 /// X86OperandMem operand instead of Variable as the destination. It's
2513 /// important for liveness that there is no Dest operand. The source must be 2513 /// important for liveness that there is no Dest operand. The source must be
2514 /// an Xmm register, since Dest is mem. 2514 /// an Xmm register, since Dest is mem.
2515 class InstX86StoreP final : public InstX86Base { 2515 class InstX86StoreP final : public InstX86Base {
2516 InstX86StoreP() = delete; 2516 InstX86StoreP() = delete;
2517 InstX86StoreP(const InstX86StoreP &) = delete; 2517 InstX86StoreP(const InstX86StoreP &) = delete;
2518 InstX86StoreP &operator=(const InstX86StoreP &) = delete; 2518 InstX86StoreP &operator=(const InstX86StoreP &) = delete;
2519 2519
2520 public: 2520 public:
2521 static InstX86StoreP *create(Cfg *Func, Variable *Value, 2521 static InstX86StoreP *create(Cfg *Func, Variable *Value,
2522 X86OperandMem *Mem) { 2522 X86OperandMem *Mem) {
2523 return new (Func->allocate<InstX86StoreP>()) 2523 return new (Func->allocate<InstX86StoreP>())
2524 InstX86StoreP(Func, Value, Mem); 2524 InstX86StoreP(Func, Value, Mem);
2525 } 2525 }
2526 void emit(const Cfg *Func) const override; 2526 void emit(const Cfg *Func) const override;
2527 void emitIAS(const Cfg *Func) const override; 2527 void emitIAS(const Cfg *Func) const override;
2528 void dump(const Cfg *Func) const override; 2528 void dump(const Cfg *Func) const override;
2529 static bool classof(const Inst *Inst) { 2529 static bool classof(const Inst *Instr) {
2530 return InstX86Base::isClassof(Inst, InstX86Base::StoreP); 2530 return InstX86Base::isClassof(Instr, InstX86Base::StoreP);
2531 } 2531 }
2532 2532
2533 private: 2533 private:
2534 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem); 2534 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem);
2535 }; 2535 };
2536 2536
2537 class InstX86StoreQ final : public InstX86Base { 2537 class InstX86StoreQ final : public InstX86Base {
2538 InstX86StoreQ() = delete; 2538 InstX86StoreQ() = delete;
2539 InstX86StoreQ(const InstX86StoreQ &) = delete; 2539 InstX86StoreQ(const InstX86StoreQ &) = delete;
2540 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete; 2540 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete;
2541 2541
2542 public: 2542 public:
2543 static InstX86StoreQ *create(Cfg *Func, Variable *Value, 2543 static InstX86StoreQ *create(Cfg *Func, Variable *Value,
2544 X86OperandMem *Mem) { 2544 X86OperandMem *Mem) {
2545 return new (Func->allocate<InstX86StoreQ>()) 2545 return new (Func->allocate<InstX86StoreQ>())
2546 InstX86StoreQ(Func, Value, Mem); 2546 InstX86StoreQ(Func, Value, Mem);
2547 } 2547 }
2548 void emit(const Cfg *Func) const override; 2548 void emit(const Cfg *Func) const override;
2549 void emitIAS(const Cfg *Func) const override; 2549 void emitIAS(const Cfg *Func) const override;
2550 void dump(const Cfg *Func) const override; 2550 void dump(const Cfg *Func) const override;
2551 static bool classof(const Inst *Inst) { 2551 static bool classof(const Inst *Instr) {
2552 return InstX86Base::isClassof(Inst, InstX86Base::StoreQ); 2552 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ);
2553 } 2553 }
2554 2554
2555 private: 2555 private:
2556 InstX86StoreQ(Cfg *Func, Variable *Value, X86OperandMem *Mem); 2556 InstX86StoreQ(Cfg *Func, Variable *Value, X86OperandMem *Mem);
2557 }; 2557 };
2558 2558
2559 /// Nop instructions of varying length 2559 /// Nop instructions of varying length
2560 class InstX86Nop final : public InstX86Base { 2560 class InstX86Nop final : public InstX86Base {
2561 InstX86Nop() = delete; 2561 InstX86Nop() = delete;
2562 InstX86Nop(const InstX86Nop &) = delete; 2562 InstX86Nop(const InstX86Nop &) = delete;
2563 InstX86Nop &operator=(const InstX86Nop &) = delete; 2563 InstX86Nop &operator=(const InstX86Nop &) = delete;
2564 2564
2565 public: 2565 public:
2566 // TODO: Replace with enum. 2566 // TODO: Replace with enum.
2567 using NopVariant = unsigned; 2567 using NopVariant = unsigned;
2568 2568
2569 static InstX86Nop *create(Cfg *Func, NopVariant Variant) { 2569 static InstX86Nop *create(Cfg *Func, NopVariant Variant) {
2570 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant); 2570 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant);
2571 } 2571 }
2572 void emit(const Cfg *Func) const override; 2572 void emit(const Cfg *Func) const override;
2573 void emitIAS(const Cfg *Func) const override; 2573 void emitIAS(const Cfg *Func) const override;
2574 void dump(const Cfg *Func) const override; 2574 void dump(const Cfg *Func) const override;
2575 static bool classof(const Inst *Inst) { 2575 static bool classof(const Inst *Instr) {
2576 return InstX86Base::isClassof(Inst, InstX86Base::Nop); 2576 return InstX86Base::isClassof(Instr, InstX86Base::Nop);
2577 } 2577 }
2578 2578
2579 private: 2579 private:
2580 InstX86Nop(Cfg *Func, SizeT Length); 2580 InstX86Nop(Cfg *Func, SizeT Length);
2581 2581
2582 NopVariant Variant; 2582 NopVariant Variant;
2583 }; 2583 };
2584 2584
2585 /// Fld - load a value onto the x87 FP stack. 2585 /// Fld - load a value onto the x87 FP stack.
2586 class InstX86Fld final : public InstX86Base { 2586 class InstX86Fld final : public InstX86Base {
2587 InstX86Fld() = delete; 2587 InstX86Fld() = delete;
2588 InstX86Fld(const InstX86Fld &) = delete; 2588 InstX86Fld(const InstX86Fld &) = delete;
2589 InstX86Fld &operator=(const InstX86Fld &) = delete; 2589 InstX86Fld &operator=(const InstX86Fld &) = delete;
2590 2590
2591 public: 2591 public:
2592 static InstX86Fld *create(Cfg *Func, Operand *Src) { 2592 static InstX86Fld *create(Cfg *Func, Operand *Src) {
2593 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src); 2593 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src);
2594 } 2594 }
2595 void emit(const Cfg *Func) const override; 2595 void emit(const Cfg *Func) const override;
2596 void emitIAS(const Cfg *Func) const override; 2596 void emitIAS(const Cfg *Func) const override;
2597 void dump(const Cfg *Func) const override; 2597 void dump(const Cfg *Func) const override;
2598 static bool classof(const Inst *Inst) { 2598 static bool classof(const Inst *Instr) {
2599 return InstX86Base::isClassof(Inst, InstX86Base::Fld); 2599 return InstX86Base::isClassof(Instr, InstX86Base::Fld);
2600 } 2600 }
2601 2601
2602 private: 2602 private:
2603 InstX86Fld(Cfg *Func, Operand *Src); 2603 InstX86Fld(Cfg *Func, Operand *Src);
2604 }; 2604 };
2605 2605
2606 /// Fstp - store x87 st(0) into memory and pop st(0). 2606 /// Fstp - store x87 st(0) into memory and pop st(0).
2607 class InstX86Fstp final : public InstX86Base { 2607 class InstX86Fstp final : public InstX86Base {
2608 InstX86Fstp() = delete; 2608 InstX86Fstp() = delete;
2609 InstX86Fstp(const InstX86Fstp &) = delete; 2609 InstX86Fstp(const InstX86Fstp &) = delete;
2610 InstX86Fstp &operator=(const InstX86Fstp &) = delete; 2610 InstX86Fstp &operator=(const InstX86Fstp &) = delete;
2611 2611
2612 public: 2612 public:
2613 static InstX86Fstp *create(Cfg *Func, Variable *Dest) { 2613 static InstX86Fstp *create(Cfg *Func, Variable *Dest) {
2614 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest); 2614 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest);
2615 } 2615 }
2616 void emit(const Cfg *Func) const override; 2616 void emit(const Cfg *Func) const override;
2617 void emitIAS(const Cfg *Func) const override; 2617 void emitIAS(const Cfg *Func) const override;
2618 void dump(const Cfg *Func) const override; 2618 void dump(const Cfg *Func) const override;
2619 static bool classof(const Inst *Inst) { 2619 static bool classof(const Inst *Instr) {
2620 return InstX86Base::isClassof(Inst, InstX86Base::Fstp); 2620 return InstX86Base::isClassof(Instr, InstX86Base::Fstp);
2621 } 2621 }
2622 2622
2623 private: 2623 private:
2624 InstX86Fstp(Cfg *Func, Variable *Dest); 2624 InstX86Fstp(Cfg *Func, Variable *Dest);
2625 }; 2625 };
2626 2626
2627 class InstX86Pop final : public InstX86Base { 2627 class InstX86Pop final : public InstX86Base {
2628 InstX86Pop() = delete; 2628 InstX86Pop() = delete;
2629 InstX86Pop(const InstX86Pop &) = delete; 2629 InstX86Pop(const InstX86Pop &) = delete;
2630 InstX86Pop &operator=(const InstX86Pop &) = delete; 2630 InstX86Pop &operator=(const InstX86Pop &) = delete;
2631 2631
2632 public: 2632 public:
2633 static InstX86Pop *create(Cfg *Func, Variable *Dest) { 2633 static InstX86Pop *create(Cfg *Func, Variable *Dest) {
2634 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest); 2634 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest);
2635 } 2635 }
2636 void emit(const Cfg *Func) const override; 2636 void emit(const Cfg *Func) const override;
2637 void emitIAS(const Cfg *Func) const override; 2637 void emitIAS(const Cfg *Func) const override;
2638 void dump(const Cfg *Func) const override; 2638 void dump(const Cfg *Func) const override;
2639 static bool classof(const Inst *Inst) { 2639 static bool classof(const Inst *Instr) {
2640 return InstX86Base::isClassof(Inst, InstX86Base::Pop); 2640 return InstX86Base::isClassof(Instr, InstX86Base::Pop);
2641 } 2641 }
2642 2642
2643 private: 2643 private:
2644 InstX86Pop(Cfg *Func, Variable *Dest); 2644 InstX86Pop(Cfg *Func, Variable *Dest);
2645 }; 2645 };
2646 2646
2647 class InstX86Push final : public InstX86Base { 2647 class InstX86Push final : public InstX86Base {
2648 InstX86Push() = delete; 2648 InstX86Push() = delete;
2649 InstX86Push(const InstX86Push &) = delete; 2649 InstX86Push(const InstX86Push &) = delete;
2650 InstX86Push &operator=(const InstX86Push &) = delete; 2650 InstX86Push &operator=(const InstX86Push &) = delete;
2651 2651
2652 public: 2652 public:
2653 static InstX86Push *create(Cfg *Func, InstX86Label *Label) { 2653 static InstX86Push *create(Cfg *Func, InstX86Label *Label) {
2654 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label); 2654 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label);
2655 } 2655 }
2656 static InstX86Push *create(Cfg *Func, Operand *Source) { 2656 static InstX86Push *create(Cfg *Func, Operand *Source) {
2657 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); 2657 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source);
2658 } 2658 }
2659 void emit(const Cfg *Func) const override; 2659 void emit(const Cfg *Func) const override;
2660 void emitIAS(const Cfg *Func) const override; 2660 void emitIAS(const Cfg *Func) const override;
2661 void dump(const Cfg *Func) const override; 2661 void dump(const Cfg *Func) const override;
2662 static bool classof(const Inst *Inst) { 2662 static bool classof(const Inst *Instr) {
2663 return InstX86Base::isClassof(Inst, InstX86Base::Push); 2663 return InstX86Base::isClassof(Instr, InstX86Base::Push);
2664 } 2664 }
2665 2665
2666 private: 2666 private:
2667 InstX86Label *Label = nullptr; 2667 InstX86Label *Label = nullptr;
2668 2668
2669 InstX86Push(Cfg *Func, Operand *Source); 2669 InstX86Push(Cfg *Func, Operand *Source);
2670 InstX86Push(Cfg *Func, InstX86Label *Label); 2670 InstX86Push(Cfg *Func, InstX86Label *Label);
2671 }; 2671 };
2672 2672
2673 /// Ret instruction. Currently only supports the "ret" version that does not 2673 /// Ret instruction. Currently only supports the "ret" version that does not
2674 /// pop arguments. This instruction takes a Source operand (for non-void 2674 /// pop arguments. This instruction takes a Source operand (for non-void
2675 /// returning functions) for liveness analysis, though a FakeUse before the 2675 /// returning functions) for liveness analysis, though a FakeUse before the
2676 /// ret would do just as well. 2676 /// ret would do just as well.
2677 class InstX86Ret final : public InstX86Base { 2677 class InstX86Ret final : public InstX86Base {
2678 InstX86Ret() = delete; 2678 InstX86Ret() = delete;
2679 InstX86Ret(const InstX86Ret &) = delete; 2679 InstX86Ret(const InstX86Ret &) = delete;
2680 InstX86Ret &operator=(const InstX86Ret &) = delete; 2680 InstX86Ret &operator=(const InstX86Ret &) = delete;
2681 2681
2682 public: 2682 public:
2683 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) { 2683 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) {
2684 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source); 2684 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source);
2685 } 2685 }
2686 void emit(const Cfg *Func) const override; 2686 void emit(const Cfg *Func) const override;
2687 void emitIAS(const Cfg *Func) const override; 2687 void emitIAS(const Cfg *Func) const override;
2688 void dump(const Cfg *Func) const override; 2688 void dump(const Cfg *Func) const override;
2689 static bool classof(const Inst *Inst) { 2689 static bool classof(const Inst *Instr) {
2690 return InstX86Base::isClassof(Inst, InstX86Base::Ret); 2690 return InstX86Base::isClassof(Instr, InstX86Base::Ret);
2691 } 2691 }
2692 2692
2693 private: 2693 private:
2694 InstX86Ret(Cfg *Func, Variable *Source); 2694 InstX86Ret(Cfg *Func, Variable *Source);
2695 }; 2695 };
2696 2696
2697 /// Conditional set-byte instruction. 2697 /// Conditional set-byte instruction.
2698 class InstX86Setcc final : public InstX86Base { 2698 class InstX86Setcc final : public InstX86Base {
2699 InstX86Setcc() = delete; 2699 InstX86Setcc() = delete;
2700 InstX86Setcc(const InstX86Cmov &) = delete; 2700 InstX86Setcc(const InstX86Cmov &) = delete;
2701 InstX86Setcc &operator=(const InstX86Setcc &) = delete; 2701 InstX86Setcc &operator=(const InstX86Setcc &) = delete;
2702 2702
2703 public: 2703 public:
2704 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) { 2704 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) {
2705 return new (Func->allocate<InstX86Setcc>()) 2705 return new (Func->allocate<InstX86Setcc>())
2706 InstX86Setcc(Func, Dest, Cond); 2706 InstX86Setcc(Func, Dest, Cond);
2707 } 2707 }
2708 void emit(const Cfg *Func) const override; 2708 void emit(const Cfg *Func) const override;
2709 void emitIAS(const Cfg *Func) const override; 2709 void emitIAS(const Cfg *Func) const override;
2710 void dump(const Cfg *Func) const override; 2710 void dump(const Cfg *Func) const override;
2711 static bool classof(const Inst *Inst) { 2711 static bool classof(const Inst *Instr) {
2712 return InstX86Base::isClassof(Inst, InstX86Base::Setcc); 2712 return InstX86Base::isClassof(Instr, InstX86Base::Setcc);
2713 } 2713 }
2714 2714
2715 private: 2715 private:
2716 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond); 2716 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond);
2717 2717
2718 const BrCond Condition; 2718 const BrCond Condition;
2719 }; 2719 };
2720 2720
2721 /// Exchanging Add instruction. Exchanges the first operand (destination 2721 /// Exchanging Add instruction. Exchanges the first operand (destination
2722 /// operand) with the second operand (source operand), then loads the sum of 2722 /// operand) with the second operand (source operand), then loads the sum of
2723 /// the two values into the destination operand. The destination may be a 2723 /// the two values into the destination operand. The destination may be a
2724 /// register or memory, while the source must be a register. 2724 /// register or memory, while the source must be a register.
2725 /// 2725 ///
2726 /// Both the dest and source are updated. The caller should then insert a 2726 /// Both the dest and source are updated. The caller should then insert a
2727 /// FakeDef to reflect the second udpate. 2727 /// FakeDef to reflect the second udpate.
2728 class InstX86Xadd final : public InstX86BaseLockable { 2728 class InstX86Xadd final : public InstX86BaseLockable {
2729 InstX86Xadd() = delete; 2729 InstX86Xadd() = delete;
2730 InstX86Xadd(const InstX86Xadd &) = delete; 2730 InstX86Xadd(const InstX86Xadd &) = delete;
2731 InstX86Xadd &operator=(const InstX86Xadd &) = delete; 2731 InstX86Xadd &operator=(const InstX86Xadd &) = delete;
2732 2732
2733 public: 2733 public:
2734 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 2734 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
2735 bool Locked) { 2735 bool Locked) {
2736 return new (Func->allocate<InstX86Xadd>()) 2736 return new (Func->allocate<InstX86Xadd>())
2737 InstX86Xadd(Func, Dest, Source, Locked); 2737 InstX86Xadd(Func, Dest, Source, Locked);
2738 } 2738 }
2739 void emit(const Cfg *Func) const override; 2739 void emit(const Cfg *Func) const override;
2740 void emitIAS(const Cfg *Func) const override; 2740 void emitIAS(const Cfg *Func) const override;
2741 void dump(const Cfg *Func) const override; 2741 void dump(const Cfg *Func) const override;
2742 static bool classof(const Inst *Inst) { 2742 static bool classof(const Inst *Instr) {
2743 return InstX86Base::isClassof(Inst, InstX86Base::Xadd); 2743 return InstX86Base::isClassof(Instr, InstX86Base::Xadd);
2744 } 2744 }
2745 2745
2746 private: 2746 private:
2747 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 2747 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
2748 }; 2748 };
2749 2749
2750 /// Exchange instruction. Exchanges the first operand (destination operand) 2750 /// Exchange instruction. Exchanges the first operand (destination operand)
2751 /// with the second operand (source operand). At least one of the operands 2751 /// with the second operand (source operand). At least one of the operands
2752 /// must be a register (and the other can be reg or mem). Both the Dest and 2752 /// must be a register (and the other can be reg or mem). Both the Dest and
2753 /// Source are updated. If there is a memory operand, then the instruction is 2753 /// Source are updated. If there is a memory operand, then the instruction is
2754 /// automatically "locked" without the need for a lock prefix. 2754 /// automatically "locked" without the need for a lock prefix.
2755 class InstX86Xchg final : public InstX86Base { 2755 class InstX86Xchg final : public InstX86Base {
2756 InstX86Xchg() = delete; 2756 InstX86Xchg() = delete;
2757 InstX86Xchg(const InstX86Xchg &) = delete; 2757 InstX86Xchg(const InstX86Xchg &) = delete;
2758 InstX86Xchg &operator=(const InstX86Xchg &) = delete; 2758 InstX86Xchg &operator=(const InstX86Xchg &) = delete;
2759 2759
2760 public: 2760 public:
2761 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 2761 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
2762 return new (Func->allocate<InstX86Xchg>()) 2762 return new (Func->allocate<InstX86Xchg>())
2763 InstX86Xchg(Func, Dest, Source); 2763 InstX86Xchg(Func, Dest, Source);
2764 } 2764 }
2765 void emit(const Cfg *Func) const override; 2765 void emit(const Cfg *Func) const override;
2766 void emitIAS(const Cfg *Func) const override; 2766 void emitIAS(const Cfg *Func) const override;
2767 void dump(const Cfg *Func) const override; 2767 void dump(const Cfg *Func) const override;
2768 static bool classof(const Inst *Inst) { 2768 static bool classof(const Inst *Instr) {
2769 return InstX86Base::isClassof(Inst, InstX86Base::Xchg); 2769 return InstX86Base::isClassof(Instr, InstX86Base::Xchg);
2770 } 2770 }
2771 2771
2772 private: 2772 private:
2773 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source); 2773 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source);
2774 }; 2774 };
2775 2775
2776 /// Start marker for the Intel Architecture Code Analyzer. This is not an 2776 /// Start marker for the Intel Architecture Code Analyzer. This is not an
2777 /// executable instruction and must only be used for analysis. 2777 /// executable instruction and must only be used for analysis.
2778 class InstX86IacaStart final : public InstX86Base { 2778 class InstX86IacaStart final : public InstX86Base {
2779 InstX86IacaStart() = delete; 2779 InstX86IacaStart() = delete;
2780 InstX86IacaStart(const InstX86IacaStart &) = delete; 2780 InstX86IacaStart(const InstX86IacaStart &) = delete;
2781 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete; 2781 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete;
2782 2782
2783 public: 2783 public:
2784 static InstX86IacaStart *create(Cfg *Func) { 2784 static InstX86IacaStart *create(Cfg *Func) {
2785 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func); 2785 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func);
2786 } 2786 }
2787 void emit(const Cfg *Func) const override; 2787 void emit(const Cfg *Func) const override;
2788 void emitIAS(const Cfg *Func) const override; 2788 void emitIAS(const Cfg *Func) const override;
2789 void dump(const Cfg *Func) const override; 2789 void dump(const Cfg *Func) const override;
2790 static bool classof(const Inst *Inst) { 2790 static bool classof(const Inst *Instr) {
2791 return InstX86Base::isClassof(Inst, InstX86Base::IacaStart); 2791 return InstX86Base::isClassof(Instr, InstX86Base::IacaStart);
2792 } 2792 }
2793 2793
2794 private: 2794 private:
2795 InstX86IacaStart(Cfg *Func); 2795 InstX86IacaStart(Cfg *Func);
2796 }; 2796 };
2797 2797
2798 /// End marker for the Intel Architecture Code Analyzer. This is not an 2798 /// End marker for the Intel Architecture Code Analyzer. This is not an
2799 /// executable instruction and must only be used for analysis. 2799 /// executable instruction and must only be used for analysis.
2800 class InstX86IacaEnd final : public InstX86Base { 2800 class InstX86IacaEnd final : public InstX86Base {
2801 InstX86IacaEnd() = delete; 2801 InstX86IacaEnd() = delete;
2802 InstX86IacaEnd(const InstX86IacaEnd &) = delete; 2802 InstX86IacaEnd(const InstX86IacaEnd &) = delete;
2803 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete; 2803 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete;
2804 2804
2805 public: 2805 public:
2806 static InstX86IacaEnd *create(Cfg *Func) { 2806 static InstX86IacaEnd *create(Cfg *Func) {
2807 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func); 2807 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func);
2808 } 2808 }
2809 void emit(const Cfg *Func) const override; 2809 void emit(const Cfg *Func) const override;
2810 void emitIAS(const Cfg *Func) const override; 2810 void emitIAS(const Cfg *Func) const override;
2811 void dump(const Cfg *Func) const override; 2811 void dump(const Cfg *Func) const override;
2812 static bool classof(const Inst *Inst) { 2812 static bool classof(const Inst *Instr) {
2813 return InstX86Base::isClassof(Inst, InstX86Base::IacaEnd); 2813 return InstX86Base::isClassof(Instr, InstX86Base::IacaEnd);
2814 } 2814 }
2815 2815
2816 private: 2816 private:
2817 InstX86IacaEnd(Cfg *Func); 2817 InstX86IacaEnd(Cfg *Func);
2818 }; 2818 };
2819 }; // struct InstImpl 2819 }; // struct InstImpl
2820 2820
2821 /// struct Insts is a template that can be used to instantiate all the X86 2821 /// struct Insts is a template that can be used to instantiate all the X86
2822 /// instructions for a target with a simple 2822 /// instructions for a target with a simple
2823 /// 2823 ///
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
3528 &InstImpl<TraitsType>::Assembler::psrl}; \ 3528 &InstImpl<TraitsType>::Assembler::psrl}; \
3529 } \ 3529 } \
3530 } 3530 }
3531 3531
3532 } // end of namespace X86NAMESPACE 3532 } // end of namespace X86NAMESPACE
3533 } // end of namespace Ice 3533 } // end of namespace Ice
3534 3534
3535 #include "IceInstX86BaseImpl.h" 3535 #include "IceInstX86BaseImpl.h"
3536 3536
3537 #endif // SUBZERO_SRC_ICEINSTX86BASE_H 3537 #endif // SUBZERO_SRC_ICEINSTX86BASE_H
OLDNEW
« no previous file with comments | « src/IceInstARM32.cpp ('k') | src/IceInstX86BaseImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698