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 X86NAMESPACE { | 31 namespace X86NAMESPACE { |
31 | 32 |
32 template <typename TraitsType> | 33 template <typename TraitsType> |
33 const char *InstImpl<TraitsType>::InstX86Base::getWidthString(Type Ty) { | 34 const char *InstImpl<TraitsType>::InstX86Base::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 Operand *Addr, | 51 Operand *Addr, |
51 InstArithmetic::OpKind Op, | 52 InstArithmetic::OpKind Op, |
52 Variable *Beacon) | 53 Variable *Beacon) |
53 : InstX86Base(Func, InstX86Base::FakeRMW, 3, nullptr), Op(Op) { | 54 : InstX86Base(Func, InstX86Base::FakeRMW, 3, nullptr), 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 <typename TraitsType> | 60 template <typename TraitsType> |
| 61 InstImpl<TraitsType>::InstX86GetIP::InstX86GetIP(Cfg *Func, Variable *Dest) |
| 62 : InstX86Base(Func, InstX86Base::GetIP, 0, Dest) {} |
| 63 |
| 64 template <typename TraitsType> |
60 InstImpl<TraitsType>::InstX86Mul::InstX86Mul(Cfg *Func, Variable *Dest, | 65 InstImpl<TraitsType>::InstX86Mul::InstX86Mul(Cfg *Func, Variable *Dest, |
61 Variable *Source1, | 66 Variable *Source1, |
62 Operand *Source2) | 67 Operand *Source2) |
63 : InstX86Base(Func, InstX86Base::Mul, 2, Dest) { | 68 : InstX86Base(Func, InstX86Base::Mul, 2, Dest) { |
64 this->addSource(Source1); | 69 this->addSource(Source1); |
65 this->addSource(Source2); | 70 this->addSource(Source2); |
66 } | 71 } |
67 | 72 |
68 template <typename TraitsType> | 73 template <typename TraitsType> |
69 InstImpl<TraitsType>::InstX86Shld::InstX86Shld(Cfg *Func, Variable *Dest, | 74 InstImpl<TraitsType>::InstX86Shld::InstX86Shld(Cfg *Func, Variable *Dest, |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 Type Ty = getData()->getType(); | 389 Type Ty = getData()->getType(); |
385 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; | 390 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; |
386 getAddr()->dump(Func); | 391 getAddr()->dump(Func); |
387 Str << ", "; | 392 Str << ", "; |
388 getData()->dump(Func); | 393 getData()->dump(Func); |
389 Str << ", beacon="; | 394 Str << ", beacon="; |
390 getBeacon()->dump(Func); | 395 getBeacon()->dump(Func); |
391 } | 396 } |
392 | 397 |
393 template <typename TraitsType> | 398 template <typename TraitsType> |
| 399 void InstImpl<TraitsType>::InstX86GetIP::emit(const Cfg *Func) const { |
| 400 if (!BuildDefs::dump()) |
| 401 return; |
| 402 Ostream &Str = Func->getContext()->getStrEmit(); |
| 403 assert(this->getDest()->hasReg()); |
| 404 Str << "\t" |
| 405 "addl\t$_GLOBAL_OFFSET_TABLE_, "; |
| 406 this->getDest()->emit(Func); |
| 407 } |
| 408 |
| 409 template <typename TraitsType> |
| 410 void InstImpl<TraitsType>::InstX86GetIP::emitIAS(const Cfg *Func) const { |
| 411 if (Func->getContext()->getFlags().getOutFileType() == FT_Iasm) { |
| 412 // TODO(stichnot): Find a workaround for llvm-mc's inability to handle |
| 413 // something like ".long _GLOBAL_OFFSET_TABLE_ + ." . One possibility is to |
| 414 // just use hybrid iasm output for this add instruction. |
| 415 llvm::report_fatal_error( |
| 416 "Iasm support for _GLOBAL_OFFSET_TABLE_ not implemented"); |
| 417 } |
| 418 Assembler *Asm = Func->getAssembler<Assembler>(); |
| 419 assert(this->getDest()->hasReg()); |
| 420 GPRRegister Reg = Traits::getEncodedGPR(this->getDest()->getRegNum()); |
| 421 Constant *GlobalOffsetTable = |
| 422 Func->getContext()->getConstantExternSym("_GLOBAL_OFFSET_TABLE_"); |
| 423 AssemblerFixup *Fixup = Asm->createFixup(Traits::FK_GotPC, GlobalOffsetTable); |
| 424 intptr_t OrigPos = Asm->getBufferSize(); |
| 425 constexpr int32_t TempDisp = 0; |
| 426 constexpr int32_t ImmediateWidth = 4; |
| 427 // Emit the add instruction once, in a preliminary fashion, to find its total |
| 428 // size. TODO(stichnot): IceType_i32 should really be something that |
| 429 // represents the target's pointer type. |
| 430 Asm->add(IceType_i32, Reg, AssemblerImmediate(TempDisp, Fixup)); |
| 431 const int32_t Disp = Asm->getBufferSize() - OrigPos - ImmediateWidth; |
| 432 // Now roll back and emit the add instruction again, this time with the |
| 433 // correct displacement. |
| 434 Asm->setBufferSize(OrigPos); |
| 435 Asm->add(IceType_i32, Reg, AssemblerImmediate(Disp, Fixup)); |
| 436 } |
| 437 |
| 438 template <typename TraitsType> |
| 439 void InstImpl<TraitsType>::InstX86GetIP::dump(const Cfg *Func) const { |
| 440 if (!BuildDefs::dump()) |
| 441 return; |
| 442 Ostream &Str = Func->getContext()->getStrDump(); |
| 443 this->getDest()->dump(Func); |
| 444 Str << " = call getIP"; |
| 445 } |
| 446 |
| 447 template <typename TraitsType> |
394 void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { | 448 void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { |
395 if (!BuildDefs::dump()) | 449 if (!BuildDefs::dump()) |
396 return; | 450 return; |
397 Ostream &Str = Func->getContext()->getStrEmit(); | 451 Ostream &Str = Func->getContext()->getStrEmit(); |
398 Str << getName(Func) << ":"; | 452 Str << getName(Func) << ":"; |
399 } | 453 } |
400 | 454 |
401 template <typename TraitsType> | 455 template <typename TraitsType> |
402 void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const { | 456 void InstImpl<TraitsType>::InstX86Label::emitIAS(const Cfg *Func) const { |
403 Assembler *Asm = Func->getAssembler<Assembler>(); | 457 Assembler *Asm = Func->getAssembler<Assembler>(); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 } else { | 726 } else { |
673 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar); | 727 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar); |
674 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 728 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
675 } | 729 } |
676 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) { | 730 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) { |
677 Mem->emitSegmentOverride(Asm); | 731 Mem->emitSegmentOverride(Asm); |
678 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); | 732 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); |
679 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 733 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
680 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); | 734 (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); |
681 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 735 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
682 AssemblerFixup *Fixup = Asm->createFixup(Traits::RelFixup, Reloc); | 736 AssemblerFixup *Fixup = |
| 737 Asm->createFixup(Traits::TargetLowering::getAbsFixup(), Reloc); |
683 (Asm->*(Emitter.GPRImm))(Ty, VarReg, | 738 (Asm->*(Emitter.GPRImm))(Ty, VarReg, |
684 AssemblerImmediate(Reloc->getOffset(), Fixup)); | 739 AssemblerImmediate(Reloc->getOffset(), Fixup)); |
685 } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) { | 740 } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) { |
686 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 741 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
687 } else { | 742 } else { |
688 llvm_unreachable("Unexpected operand type"); | 743 llvm_unreachable("Unexpected operand type"); |
689 } | 744 } |
690 } | 745 } |
691 | 746 |
692 template <typename TraitsType> | 747 template <typename TraitsType> |
693 void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, | 748 void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, |
694 const Address &Addr, | 749 const Address &Addr, |
695 const Operand *Src, | 750 const Operand *Src, |
696 const GPREmitterAddrOp &Emitter) { | 751 const GPREmitterAddrOp &Emitter) { |
697 Assembler *Asm = Func->getAssembler<Assembler>(); | 752 Assembler *Asm = Func->getAssembler<Assembler>(); |
698 // Src can only be Reg or AssemblerImmediate. | 753 // Src can only be Reg or AssemblerImmediate. |
699 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 754 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
700 assert(SrcVar->hasReg()); | 755 assert(SrcVar->hasReg()); |
701 GPRRegister SrcReg = Traits::getEncodedGPR(SrcVar->getRegNum()); | 756 GPRRegister SrcReg = Traits::getEncodedGPR(SrcVar->getRegNum()); |
702 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 757 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
703 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 758 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
704 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); | 759 (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); |
705 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 760 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
706 AssemblerFixup *Fixup = Asm->createFixup(Traits::RelFixup, Reloc); | 761 AssemblerFixup *Fixup = |
| 762 Asm->createFixup(Traits::TargetLowering::getAbsFixup(), Reloc); |
707 (Asm->*(Emitter.AddrImm))(Ty, Addr, | 763 (Asm->*(Emitter.AddrImm))(Ty, Addr, |
708 AssemblerImmediate(Reloc->getOffset(), Fixup)); | 764 AssemblerImmediate(Reloc->getOffset(), Fixup)); |
709 } else { | 765 } else { |
710 llvm_unreachable("Unexpected operand type"); | 766 llvm_unreachable("Unexpected operand type"); |
711 } | 767 } |
712 } | 768 } |
713 | 769 |
714 template <typename TraitsType> | 770 template <typename TraitsType> |
715 void InstImpl<TraitsType>::emitIASAsAddrOpTyGPR( | 771 void InstImpl<TraitsType>::emitIASAsAddrOpTyGPR( |
716 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 772 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
(...skipping 2071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2788 return; | 2844 return; |
2789 Ostream &Str = Func->getContext()->getStrDump(); | 2845 Ostream &Str = Func->getContext()->getStrDump(); |
2790 Str << "IACA_END"; | 2846 Str << "IACA_END"; |
2791 } | 2847 } |
2792 | 2848 |
2793 } // end of namespace X86NAMESPACE | 2849 } // end of namespace X86NAMESPACE |
2794 | 2850 |
2795 } // end of namespace Ice | 2851 } // end of namespace Ice |
2796 | 2852 |
2797 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 2853 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
OLD | NEW |