Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.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 |
| 11 /// \brief Implements the InstX86Base class and its descendants. | 11 /// \brief Implements the InstX86Base class and its descendants. |
| 12 /// | 12 /// |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 15 #ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| 16 #define SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 16 #define SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| 17 | 17 |
| 18 #include "IceInstX86Base.h" | 18 #include "IceInstX86Base.h" |
| 19 | 19 |
| 20 #include "IceAssemblerX86Base.h" | 20 #include "IceAssemblerX86Base.h" |
| 21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
| 22 #include "IceCfgNode.h" | 22 #include "IceCfgNode.h" |
| 23 #include "IceDefs.h" | 23 #include "IceDefs.h" |
| 24 #include "IceInst.h" | 24 #include "IceInst.h" |
| 25 #include "IceOperand.h" | 25 #include "IceOperand.h" |
| 26 #include "IceTargetLowering.h" | 26 #include "IceTargetLowering.h" |
| 27 #include "IceTargetLoweringX86Base.h" | |
| 27 | 28 |
| 28 namespace Ice { | 29 namespace Ice { |
| 29 | 30 |
| 30 namespace X86Internal { | 31 namespace X86Internal { |
| 31 | 32 |
| 32 template <class Machine> | 33 template <class Machine> |
| 33 const char *InstX86Base<Machine>::getWidthString(Type Ty) { | 34 const char *InstX86Base<Machine>::getWidthString(Type Ty) { |
| 34 return Traits::TypeAttributes[Ty].WidthString; | 35 return Traits::TypeAttributes[Ty].WidthString; |
| 35 } | 36 } |
| 36 | 37 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 50 InstArithmetic::OpKind Op, | 51 InstArithmetic::OpKind Op, |
| 51 Variable *Beacon) | 52 Variable *Beacon) |
| 52 : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr), | 53 : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr), |
| 53 Op(Op) { | 54 Op(Op) { |
| 54 this->addSource(Data); | 55 this->addSource(Data); |
| 55 this->addSource(Addr); | 56 this->addSource(Addr); |
| 56 this->addSource(Beacon); | 57 this->addSource(Beacon); |
| 57 } | 58 } |
| 58 | 59 |
| 59 template <class Machine> | 60 template <class Machine> |
| 61 InstX86GetIP<Machine>::InstX86GetIP(Cfg *Func, Variable *Dest) | |
| 62 : InstX86Base<Machine>(Func, InstX86Base<Machine>::GetIP, 0, Dest) {} | |
| 63 | |
| 64 template <class Machine> | |
| 60 InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, | 65 InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, |
| 61 Operand *Source2) | 66 Operand *Source2) |
| 62 : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) { | 67 : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) { |
| 63 this->addSource(Source1); | 68 this->addSource(Source1); |
| 64 this->addSource(Source2); | 69 this->addSource(Source2); |
| 65 } | 70 } |
| 66 | 71 |
| 67 template <class Machine> | 72 template <class Machine> |
| 68 InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, | 73 InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, |
| 69 Operand *Source2) | 74 Operand *Source2) |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 Type Ty = getData()->getType(); | 394 Type Ty = getData()->getType(); |
| 390 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; | 395 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; |
| 391 getAddr()->dump(Func); | 396 getAddr()->dump(Func); |
| 392 Str << ", "; | 397 Str << ", "; |
| 393 getData()->dump(Func); | 398 getData()->dump(Func); |
| 394 Str << ", beacon="; | 399 Str << ", beacon="; |
| 395 getBeacon()->dump(Func); | 400 getBeacon()->dump(Func); |
| 396 } | 401 } |
| 397 | 402 |
| 398 template <class Machine> | 403 template <class Machine> |
| 404 void InstX86GetIP<Machine>::emit(const Cfg *Func) const { | |
| 405 if (!BuildDefs::dump()) | |
| 406 return; | |
| 407 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 408 assert(this->getDest()->hasReg()); | |
| 409 Str << "\t" | |
| 410 "addl\t$_GLOBAL_OFFSET_TABLE_, "; | |
| 411 this->getDest()->emit(Func); | |
| 412 } | |
| 413 | |
| 414 template <class Machine> | |
| 415 void InstX86GetIP<Machine>::emitIAS(const Cfg *Func) const { | |
| 416 if (Func->getContext()->getFlags().getOutFileType() == FT_Iasm) { | |
| 417 // TODO(stichnot): Find a workaround for llvm-mc's inability to handle | |
| 418 // something like ".long _GLOBAL_OFFSET_TABLE_ + ." . One possibility is to | |
| 419 // just use hybrid iasm output for this add instruction. | |
| 420 llvm::report_fatal_error( | |
| 421 "Iasm support for _GLOBAL_OFFSET_TABLE_ not implemented"); | |
| 422 } | |
| 423 typename InstX86Base<Machine>::Traits::Assembler *Asm = | |
| 424 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | |
| 425 assert(this->getDest()->hasReg()); | |
| 426 typename InstX86Base<Machine>::Traits::GPRRegister Reg = | |
| 427 InstX86Base<Machine>::Traits::getEncodedGPR(this->getDest()->getRegNum()); | |
| 428 Constant *GlobalOffsetTable = | |
| 429 Func->getContext()->getConstantExternSym("_GLOBAL_OFFSET_TABLE_"); | |
| 430 AssemblerFixup *Fixup = Asm->createFixup( | |
| 431 InstX86Base<Machine>::Traits::FK_GotPC, GlobalOffsetTable); | |
| 432 intptr_t OrigPos = Asm->getBufferSize(); | |
| 433 constexpr int32_t TempDisp = 0; | |
| 434 constexpr int32_t ImmediateWidth = 4; | |
| 435 // Emit the add instruction once, in a preliminary fashion, to find its total | |
| 436 // size. | |
| 437 Asm->add(IceType_i32, Reg, Immediate(TempDisp, Fixup)); | |
|
John
2016/01/04 21:33:51
This should really be Traits::PointerType (not cur
Jim Stichnoth
2016/01/04 23:32:12
Done.
| |
| 438 const int32_t Disp = Asm->getBufferSize() - OrigPos - ImmediateWidth; | |
| 439 // Now roll back and emit the add instruction again, this time with the | |
| 440 // correct displacement. | |
| 441 Asm->setBufferSize(OrigPos); | |
| 442 Asm->add(IceType_i32, Reg, Immediate(Disp, Fixup)); | |
| 443 } | |
| 444 | |
| 445 template <class Machine> | |
| 446 void InstX86GetIP<Machine>::dump(const Cfg *Func) const { | |
| 447 if (!BuildDefs::dump()) | |
| 448 return; | |
| 449 Ostream &Str = Func->getContext()->getStrDump(); | |
| 450 this->getDest()->dump(Func); | |
| 451 Str << " = call getIP"; | |
| 452 } | |
| 453 | |
| 454 template <class Machine> | |
| 399 void InstX86Label<Machine>::emit(const Cfg *Func) const { | 455 void InstX86Label<Machine>::emit(const Cfg *Func) const { |
| 400 if (!BuildDefs::dump()) | 456 if (!BuildDefs::dump()) |
| 401 return; | 457 return; |
| 402 Ostream &Str = Func->getContext()->getStrEmit(); | 458 Ostream &Str = Func->getContext()->getStrEmit(); |
| 403 Str << getName(Func) << ":"; | 459 Str << getName(Func) << ":"; |
| 404 } | 460 } |
| 405 | 461 |
| 406 template <class Machine> | 462 template <class Machine> |
| 407 void InstX86Label<Machine>::emitIAS(const Cfg *Func) const { | 463 void InstX86Label<Machine>::emitIAS(const Cfg *Func) const { |
| 408 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 464 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 753 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 698 } | 754 } |
| 699 } else if (const auto *Mem = llvm::dyn_cast< | 755 } else if (const auto *Mem = llvm::dyn_cast< |
| 700 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 756 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 701 Mem->emitSegmentOverride(Asm); | 757 Mem->emitSegmentOverride(Asm); |
| 702 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); | 758 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); |
| 703 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 759 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 704 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); | 760 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 705 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 761 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 706 AssemblerFixup *Fixup = | 762 AssemblerFixup *Fixup = |
| 707 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 763 Asm->createFixup(TargetX86Base<Machine>::getAbsFixup(), Reloc); |
| 708 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); | 764 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| 709 } else if (const auto *Split = llvm::dyn_cast< | 765 } else if (const auto *Split = llvm::dyn_cast< |
| 710 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { | 766 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| 711 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 767 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 712 } else { | 768 } else { |
| 713 llvm_unreachable("Unexpected operand type"); | 769 llvm_unreachable("Unexpected operand type"); |
| 714 } | 770 } |
| 715 } | 771 } |
| 716 | 772 |
| 717 template <class Machine> | 773 template <class Machine> |
| 718 void emitIASAddrOpTyGPR( | 774 void emitIASAddrOpTyGPR( |
| 719 const Cfg *Func, Type Ty, | 775 const Cfg *Func, Type Ty, |
| 720 const typename InstX86Base<Machine>::Traits::Address &Addr, | 776 const typename InstX86Base<Machine>::Traits::Address &Addr, |
| 721 const Operand *Src, | 777 const Operand *Src, |
| 722 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 778 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| 723 &Emitter) { | 779 &Emitter) { |
| 724 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 780 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 725 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 781 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 726 // Src can only be Reg or Immediate. | 782 // Src can only be Reg or Immediate. |
| 727 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 783 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 728 assert(SrcVar->hasReg()); | 784 assert(SrcVar->hasReg()); |
| 729 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 785 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 730 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); | 786 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); |
| 731 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 787 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 732 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 788 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 733 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); | 789 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| 734 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 790 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 735 AssemblerFixup *Fixup = | 791 AssemblerFixup *Fixup = |
| 736 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 792 Asm->createFixup(TargetX86Base<Machine>::getAbsFixup(), Reloc); |
| 737 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); | 793 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| 738 } else { | 794 } else { |
| 739 llvm_unreachable("Unexpected operand type"); | 795 llvm_unreachable("Unexpected operand type"); |
| 740 } | 796 } |
| 741 } | 797 } |
| 742 | 798 |
| 743 template <class Machine> | 799 template <class Machine> |
| 744 void emitIASAsAddrOpTyGPR( | 800 void emitIASAsAddrOpTyGPR( |
| 745 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 801 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 746 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 802 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| (...skipping 2333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3080 return; | 3136 return; |
| 3081 Ostream &Str = Func->getContext()->getStrDump(); | 3137 Ostream &Str = Func->getContext()->getStrDump(); |
| 3082 Str << "IACA_END"; | 3138 Str << "IACA_END"; |
| 3083 } | 3139 } |
| 3084 | 3140 |
| 3085 } // end of namespace X86Internal | 3141 } // end of namespace X86Internal |
| 3086 | 3142 |
| 3087 } // end of namespace Ice | 3143 } // end of namespace Ice |
| 3088 | 3144 |
| 3089 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3145 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |