OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |