| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - Low-level 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 // This file declares the InstX8632 and OperandX8632 classes and | 10 // This file declares the InstX8632 and OperandX8632 classes and |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 virtual void dump(const Cfg *Func) const; | 422 virtual void dump(const Cfg *Func) const; |
| 423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 424 | 424 |
| 425 private: | 425 private: |
| 426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 429 virtual ~InstX8632Call() {} | 429 virtual ~InstX8632Call() {} |
| 430 }; | 430 }; |
| 431 | 431 |
| 432 // Emit a one-operand (GPR) instruction. |
| 433 void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 434 const x86::AssemblerX86::GPREmitterOneOp &Emitter); |
| 435 |
| 432 // Instructions of the form x := op(x). | 436 // Instructions of the form x := op(x). |
| 433 template <InstX8632::InstKindX8632 K> | 437 template <InstX8632::InstKindX8632 K> |
| 434 class InstX8632Inplaceop : public InstX8632 { | 438 class InstX8632InplaceopGPR : public InstX8632 { |
| 435 public: | 439 public: |
| 436 static InstX8632Inplaceop *create(Cfg *Func, Operand *SrcDest) { | 440 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
| 437 return new (Func->allocate<InstX8632Inplaceop>()) | 441 return new (Func->allocate<InstX8632InplaceopGPR>()) |
| 438 InstX8632Inplaceop(Func, SrcDest); | 442 InstX8632InplaceopGPR(Func, SrcDest); |
| 439 } | 443 } |
| 440 virtual void emit(const Cfg *Func) const { | 444 virtual void emit(const Cfg *Func) const { |
| 441 Ostream &Str = Func->getContext()->getStrEmit(); | 445 Ostream &Str = Func->getContext()->getStrEmit(); |
| 442 assert(getSrcSize() == 1); | 446 assert(getSrcSize() == 1); |
| 443 Str << "\t" << Opcode << "\t"; | 447 Str << "\t" << Opcode << "\t"; |
| 444 getSrc(0)->emit(Func); | 448 getSrc(0)->emit(Func); |
| 445 Str << "\n"; | 449 Str << "\n"; |
| 446 } | 450 } |
| 451 virtual void emitIAS(const Cfg *Func) const { |
| 452 assert(getSrcSize() == 1); |
| 453 const Variable *Var = getDest(); |
| 454 Type Ty = Var->getType(); |
| 455 emitIASVarTyGPR(Func, Ty, Var, Emitter); |
| 456 } |
| 447 virtual void dump(const Cfg *Func) const { | 457 virtual void dump(const Cfg *Func) const { |
| 448 Ostream &Str = Func->getContext()->getStrDump(); | 458 Ostream &Str = Func->getContext()->getStrDump(); |
| 449 dumpDest(Func); | 459 dumpDest(Func); |
| 450 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 460 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 451 dumpSources(Func); | 461 dumpSources(Func); |
| 452 } | 462 } |
| 453 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 463 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 454 | 464 |
| 455 private: | 465 private: |
| 456 InstX8632Inplaceop(Cfg *Func, Operand *SrcDest) | 466 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) |
| 457 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { | 467 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| 458 addSource(SrcDest); | 468 addSource(SrcDest); |
| 459 } | 469 } |
| 460 InstX8632Inplaceop(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION; | 470 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
| 461 InstX8632Inplaceop & | 471 InstX8632InplaceopGPR & |
| 462 operator=(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION; | 472 operator=(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
| 463 virtual ~InstX8632Inplaceop() {} | 473 virtual ~InstX8632InplaceopGPR() {} |
| 464 static const char *Opcode; | 474 static const char *Opcode; |
| 475 static const x86::AssemblerX86::GPREmitterOneOp Emitter; |
| 465 }; | 476 }; |
| 466 | 477 |
| 478 // Emit a two-operand (GPR) instruction, where the dest operand is a |
| 479 // Variable that's guaranteed to be a register. |
| 480 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, |
| 481 const Operand *Src, |
| 482 const x86::AssemblerX86::GPREmitterRegOp &Emitter); |
| 483 |
| 467 // Instructions of the form x := op(y) | 484 // Instructions of the form x := op(y) |
| 468 template <InstX8632::InstKindX8632 K> | 485 template <InstX8632::InstKindX8632 K> |
| 469 class InstX8632Unaryop : public InstX8632 { | 486 class InstX8632UnaryopGPR : public InstX8632 { |
| 470 public: | 487 public: |
| 471 static InstX8632Unaryop *create(Cfg *Func, Variable *Dest, Operand *Src) { | 488 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 472 return new (Func->allocate<InstX8632Unaryop>()) | 489 return new (Func->allocate<InstX8632UnaryopGPR>()) |
| 473 InstX8632Unaryop(Func, Dest, Src); | 490 InstX8632UnaryopGPR(Func, Dest, Src); |
| 474 } | 491 } |
| 475 virtual void emit(const Cfg *Func) const { | 492 virtual void emit(const Cfg *Func) const { |
| 476 Ostream &Str = Func->getContext()->getStrEmit(); | 493 Ostream &Str = Func->getContext()->getStrEmit(); |
| 477 assert(getSrcSize() == 1); | 494 assert(getSrcSize() == 1); |
| 478 Str << "\t" << Opcode << "\t"; | 495 Str << "\t" << Opcode << "\t"; |
| 479 getDest()->emit(Func); | 496 getDest()->emit(Func); |
| 480 Str << ", "; | 497 Str << ", "; |
| 481 getSrc(0)->emit(Func); | 498 getSrc(0)->emit(Func); |
| 482 Str << "\n"; | 499 Str << "\n"; |
| 483 } | 500 } |
| 484 virtual void emitIAS(const Cfg *Func) const { emit(Func); } | 501 virtual void emitIAS(const Cfg *Func) const { |
| 502 assert(getSrcSize() == 1); |
| 503 const Variable *Var = getDest(); |
| 504 Type Ty = Var->getType(); |
| 505 const Operand *Src = getSrc(0); |
| 506 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 507 } |
| 485 virtual void dump(const Cfg *Func) const { | 508 virtual void dump(const Cfg *Func) const { |
| 486 Ostream &Str = Func->getContext()->getStrDump(); | 509 Ostream &Str = Func->getContext()->getStrDump(); |
| 487 dumpDest(Func); | 510 dumpDest(Func); |
| 488 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 511 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 489 dumpSources(Func); | 512 dumpSources(Func); |
| 490 } | 513 } |
| 491 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 514 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 492 | 515 |
| 493 private: | 516 private: |
| 494 InstX8632Unaryop(Cfg *Func, Variable *Dest, Operand *Src) | 517 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) |
| 495 : InstX8632(Func, K, 1, Dest) { | 518 : InstX8632(Func, K, 1, Dest) { |
| 496 addSource(Src); | 519 addSource(Src); |
| 497 } | 520 } |
| 498 InstX8632Unaryop(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | 521 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
| 499 InstX8632Unaryop &operator=(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | 522 InstX8632UnaryopGPR & |
| 500 virtual ~InstX8632Unaryop() {} | 523 operator=(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
| 524 virtual ~InstX8632UnaryopGPR() {} |
| 501 static const char *Opcode; | 525 static const char *Opcode; |
| 526 static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
| 502 }; | 527 }; |
| 503 | 528 |
| 504 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 529 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 505 const Operand *Src, | 530 const Operand *Src, |
| 506 const x86::AssemblerX86::TypedXmmEmitters &Emitter); | 531 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter); |
| 507 | 532 |
| 508 template <InstX8632::InstKindX8632 K> | 533 template <InstX8632::InstKindX8632 K> |
| 509 class InstX8632UnaryopXmm : public InstX8632 { | 534 class InstX8632UnaryopXmm : public InstX8632 { |
| 510 public: | 535 public: |
| 511 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { | 536 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 512 return new (Func->allocate<InstX8632UnaryopXmm>()) | 537 return new (Func->allocate<InstX8632UnaryopXmm>()) |
| 513 InstX8632UnaryopXmm(Func, Dest, Src); | 538 InstX8632UnaryopXmm(Func, Dest, Src); |
| 514 } | 539 } |
| 515 virtual void emit(const Cfg *Func) const { | 540 virtual void emit(const Cfg *Func) const { |
| 516 Ostream &Str = Func->getContext()->getStrEmit(); | 541 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 537 private: | 562 private: |
| 538 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) | 563 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) |
| 539 : InstX8632(Func, K, 1, Dest) { | 564 : InstX8632(Func, K, 1, Dest) { |
| 540 addSource(Src); | 565 addSource(Src); |
| 541 } | 566 } |
| 542 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 567 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
| 543 InstX8632UnaryopXmm & | 568 InstX8632UnaryopXmm & |
| 544 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 569 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
| 545 virtual ~InstX8632UnaryopXmm() {} | 570 virtual ~InstX8632UnaryopXmm() {} |
| 546 static const char *Opcode; | 571 static const char *Opcode; |
| 547 static const x86::AssemblerX86::TypedXmmEmitters Emitter; | 572 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
| 548 }; | 573 }; |
| 549 | 574 |
| 550 // See the definition of emitTwoAddress() for a description of | 575 // See the definition of emitTwoAddress() for a description of |
| 551 // ShiftHack. | 576 // ShiftHack. |
| 552 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 577 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| 553 bool ShiftHack = false); | 578 bool ShiftHack = false); |
| 554 | 579 |
| 555 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 580 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> |
| 556 class InstX8632Binop : public InstX8632 { | 581 class InstX8632Binop : public InstX8632 { |
| 557 public: | 582 public: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 private: | 638 private: |
| 614 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) | 639 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) |
| 615 : InstX8632(Func, K, 2, Dest) { | 640 : InstX8632(Func, K, 2, Dest) { |
| 616 addSource(Dest); | 641 addSource(Dest); |
| 617 addSource(Source); | 642 addSource(Source); |
| 618 } | 643 } |
| 619 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 644 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
| 620 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 645 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
| 621 virtual ~InstX8632BinopXmm() {} | 646 virtual ~InstX8632BinopXmm() {} |
| 622 static const char *Opcode; | 647 static const char *Opcode; |
| 623 static const x86::AssemblerX86::TypedXmmEmitters Emitter; | 648 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
| 624 }; | 649 }; |
| 625 | 650 |
| 626 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { | 651 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { |
| 627 public: | 652 public: |
| 628 // Create a ternary-op instruction like div or idiv. | 653 // Create a ternary-op instruction like div or idiv. |
| 629 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 654 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
| 630 Operand *Source2) { | 655 Operand *Source2) { |
| 631 return new (Func->allocate<InstX8632Ternop>()) | 656 return new (Func->allocate<InstX8632Ternop>()) |
| 632 InstX8632Ternop(Func, Dest, Source1, Source2); | 657 InstX8632Ternop(Func, Dest, Source1, Source2); |
| 633 } | 658 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 : InstX8632(Func, K, 1, Dest) { | 759 : InstX8632(Func, K, 1, Dest) { |
| 735 addSource(Source); | 760 addSource(Source); |
| 736 } | 761 } |
| 737 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 762 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
| 738 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 763 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
| 739 virtual ~InstX8632Movlike() {} | 764 virtual ~InstX8632Movlike() {} |
| 740 | 765 |
| 741 static const char *Opcode; | 766 static const char *Opcode; |
| 742 }; | 767 }; |
| 743 | 768 |
| 744 typedef InstX8632Inplaceop<InstX8632::Bswap> InstX8632Bswap; | 769 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; |
| 745 typedef InstX8632Inplaceop<InstX8632::Neg> InstX8632Neg; | 770 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; |
| 746 typedef InstX8632Unaryop<InstX8632::Bsf> InstX8632Bsf; | 771 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; |
| 747 typedef InstX8632Unaryop<InstX8632::Bsr> InstX8632Bsr; | 772 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; |
| 748 typedef InstX8632Unaryop<InstX8632::Lea> InstX8632Lea; | 773 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; |
| 749 typedef InstX8632Unaryop<InstX8632::Movd> InstX8632Movd; | 774 // Cbwdq instruction - wrapper for cbw, cwd, and cdq |
| 775 typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq; |
| 776 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; |
| 750 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; | 777 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; |
| 751 // Cbwdq instruction - wrapper for cbw, cwd, and cdq | |
| 752 typedef InstX8632Unaryop<InstX8632::Cbwdq> InstX8632Cbwdq; | |
| 753 // Move/assignment instruction - wrapper for mov/movss/movsd. | 778 // Move/assignment instruction - wrapper for mov/movss/movsd. |
| 754 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; | 779 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; |
| 755 // Move packed - copy 128 bit values between XMM registers, or mem128 | 780 // Move packed - copy 128 bit values between XMM registers, or mem128 |
| 756 // and XMM registers. | 781 // and XMM registers. |
| 757 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; | 782 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; |
| 758 // Movq - copy between XMM registers, or mem64 and XMM registers. | 783 // Movq - copy between XMM registers, or mem64 and XMM registers. |
| 759 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; | 784 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; |
| 760 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; | 785 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; |
| 761 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; | 786 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; |
| 762 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; | 787 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 template <> void InstX8632Pinsr::emit(const Cfg *Func) const; | 1402 template <> void InstX8632Pinsr::emit(const Cfg *Func) const; |
| 1378 template <> void InstX8632Pmull::emit(const Cfg *Func) const; | 1403 template <> void InstX8632Pmull::emit(const Cfg *Func) const; |
| 1379 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const; | 1404 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const; |
| 1380 template <> void InstX8632Psll::emit(const Cfg *Func) const; | 1405 template <> void InstX8632Psll::emit(const Cfg *Func) const; |
| 1381 template <> void InstX8632Psra::emit(const Cfg *Func) const; | 1406 template <> void InstX8632Psra::emit(const Cfg *Func) const; |
| 1382 template <> void InstX8632Psub::emit(const Cfg *Func) const; | 1407 template <> void InstX8632Psub::emit(const Cfg *Func) const; |
| 1383 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; | 1408 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; |
| 1384 template <> void InstX8632Subss::emit(const Cfg *Func) const; | 1409 template <> void InstX8632Subss::emit(const Cfg *Func) const; |
| 1385 | 1410 |
| 1386 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; | 1411 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; |
| 1412 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; |
| 1387 | 1413 |
| 1388 } // end of namespace Ice | 1414 } // end of namespace Ice |
| 1389 | 1415 |
| 1390 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1416 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |