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 |