| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 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 14 matching lines...) Expand all Loading... |
| 25 std::unique_ptr<::Ice::TargetDataLowering> | 25 std::unique_ptr<::Ice::TargetDataLowering> |
| 26 createTargetDataLowering(::Ice::GlobalContext *Ctx) { | 26 createTargetDataLowering(::Ice::GlobalContext *Ctx) { |
| 27 return ::Ice::X8632::TargetDataX8632::create(Ctx); | 27 return ::Ice::X8632::TargetDataX8632::create(Ctx); |
| 28 } | 28 } |
| 29 | 29 |
| 30 std::unique_ptr<::Ice::TargetHeaderLowering> | 30 std::unique_ptr<::Ice::TargetHeaderLowering> |
| 31 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) { | 31 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) { |
| 32 return ::Ice::X8632::TargetHeaderX8632::create(Ctx); | 32 return ::Ice::X8632::TargetHeaderX8632::create(Ctx); |
| 33 } | 33 } |
| 34 | 34 |
| 35 void staticInit() { ::Ice::X8632::TargetX8632::staticInit(); } | 35 void staticInit(const ::Ice::ClFlags &Flags) { |
| 36 ::Ice::X8632::TargetX8632::staticInit(Flags); |
| 37 } |
| 36 } // end of namespace X8632 | 38 } // end of namespace X8632 |
| 37 | 39 |
| 38 namespace Ice { | 40 namespace Ice { |
| 39 namespace X8632 { | 41 namespace X8632 { |
| 40 | 42 |
| 41 //------------------------------------------------------------------------------ | 43 //------------------------------------------------------------------------------ |
| 42 // ______ ______ ______ __ ______ ______ | 44 // ______ ______ ______ __ ______ ______ |
| 43 // /\__ _\ /\ == \ /\ __ \ /\ \ /\__ _\ /\ ___\ | 45 // /\__ _\ /\ == \ /\ __ \ /\ \ /\__ _\ /\ ___\ |
| 44 // \/_/\ \/ \ \ __< \ \ __ \ \ \ \ \/_/\ \/ \ \___ \ | 46 // \/_/\ \/ \ \ __< \ \ __ \ \ \ \ \/_/\ \/ \ \___ \ |
| 45 // \ \_\ \ \_\ \_\ \ \_\ \_\ \ \_\ \ \_\ \/\_____\ | 47 // \ \_\ \ \_\ \_\ \ \_\ \_\ \ \_\ \ \_\ \/\_____\ |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 107 |
| 106 template <> | 108 template <> |
| 107 std::array<llvm::SmallBitVector, | 109 std::array<llvm::SmallBitVector, |
| 108 TargetX86Base<X8632::Traits>::Traits::RegisterSet::Reg_NUM> | 110 TargetX86Base<X8632::Traits>::Traits::RegisterSet::Reg_NUM> |
| 109 TargetX86Base<X8632::Traits>::RegisterAliases = {{}}; | 111 TargetX86Base<X8632::Traits>::RegisterAliases = {{}}; |
| 110 | 112 |
| 111 template <> | 113 template <> |
| 112 llvm::SmallBitVector | 114 llvm::SmallBitVector |
| 113 TargetX86Base<X8632::Traits>::ScratchRegs = llvm::SmallBitVector(); | 115 TargetX86Base<X8632::Traits>::ScratchRegs = llvm::SmallBitVector(); |
| 114 | 116 |
| 117 template <> |
| 118 FixupKind TargetX86Base<X8632::Traits>::PcRelFixup = |
| 119 TargetX86Base<X8632::Traits>::Traits::FK_PcRel; |
| 120 |
| 121 template <> |
| 122 FixupKind TargetX86Base<X8632::Traits>::AbsFixup = |
| 123 TargetX86Base<X8632::Traits>::Traits::FK_Abs; |
| 124 |
| 115 //------------------------------------------------------------------------------ | 125 //------------------------------------------------------------------------------ |
| 116 // __ ______ __ __ ______ ______ __ __ __ ______ | 126 // __ ______ __ __ ______ ______ __ __ __ ______ |
| 117 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ | 127 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ |
| 118 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ | 128 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ |
| 119 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ | 129 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ |
| 120 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ | 130 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ |
| 121 // | 131 // |
| 122 //------------------------------------------------------------------------------ | 132 //------------------------------------------------------------------------------ |
| 123 void TargetX8632::lowerCall(const InstCall *Instr) { | 133 void TargetX8632::lowerCall(const InstCall *Instr) { |
| 124 // x86-32 calling convention: | 134 // x86-32 calling convention: |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 case IceType_v8i1: | 243 case IceType_v8i1: |
| 234 case IceType_v16i1: | 244 case IceType_v16i1: |
| 235 case IceType_v16i8: | 245 case IceType_v16i8: |
| 236 case IceType_v8i16: | 246 case IceType_v8i16: |
| 237 case IceType_v4i32: | 247 case IceType_v4i32: |
| 238 case IceType_v4f32: | 248 case IceType_v4f32: |
| 239 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); | 249 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); |
| 240 break; | 250 break; |
| 241 } | 251 } |
| 242 } | 252 } |
| 243 Operand *CallTarget = legalize(Instr->getCallTarget()); | 253 Operand *CallTarget = |
| 254 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); |
| 244 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 255 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
| 245 if (NeedSandboxing) { | 256 if (NeedSandboxing) { |
| 246 if (llvm::isa<Constant>(CallTarget)) { | 257 if (llvm::isa<Constant>(CallTarget)) { |
| 247 _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 258 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
| 248 } else { | 259 } else { |
| 249 Variable *CallTargetVar = nullptr; | 260 Variable *CallTargetVar = nullptr; |
| 250 _mov(CallTargetVar, CallTarget); | 261 _mov(CallTargetVar, CallTarget); |
| 251 _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 262 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
| 252 const SizeT BundleSize = | 263 const SizeT BundleSize = |
| 253 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 264 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 | 559 |
| 549 // Fill in stack offsets for stack args, and copy args into registers for | 560 // Fill in stack offsets for stack args, and copy args into registers for |
| 550 // those that were register-allocated. Args are pushed right to left, so | 561 // those that were register-allocated. Args are pushed right to left, so |
| 551 // Arg[0] is closest to the stack/frame pointer. | 562 // Arg[0] is closest to the stack/frame pointer. |
| 552 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); | 563 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); |
| 553 size_t BasicFrameOffset = | 564 size_t BasicFrameOffset = |
| 554 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES; | 565 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES; |
| 555 if (!IsEbpBasedFrame) | 566 if (!IsEbpBasedFrame) |
| 556 BasicFrameOffset += SpillAreaSizeBytes; | 567 BasicFrameOffset += SpillAreaSizeBytes; |
| 557 | 568 |
| 569 // If there is a non-deleted InstX86GetIP instruction, we need to move it to |
| 570 // the point after the stack frame has stabilized but before |
| 571 // register-allocated in-args are copied into their home registers. It would |
| 572 // be slightly faster to search for the GetIP instruction before other prolog |
| 573 // instructions are inserted, but it's more clear to do the whole |
| 574 // transformation in a single place. |
| 575 Traits::Insts::GetIP *GetIPInst = nullptr; |
| 576 if (Ctx->getFlags().getUseNonsfi()) { |
| 577 for (Inst &Instr : Node->getInsts()) { |
| 578 if (auto *GetIP = llvm::dyn_cast<Traits::Insts::GetIP>(&Instr)) { |
| 579 if (!Instr.isDeleted()) |
| 580 GetIPInst = GetIP; |
| 581 break; |
| 582 } |
| 583 } |
| 584 } |
| 585 // Delete any existing InstX86GetIP instruction and reinsert it here. Also, |
| 586 // insert the call to the helper function and the spill to the stack, to |
| 587 // simplify emission. |
| 588 if (GetIPInst) { |
| 589 GetIPInst->setDeleted(); |
| 590 Variable *Dest = GetIPInst->getDest(); |
| 591 Variable *CallDest = |
| 592 Dest->hasReg() ? Dest |
| 593 : getPhysicalRegister(Traits::RegisterSet::Reg_eax); |
| 594 // Call the getIP_<reg> helper. |
| 595 IceString RegName = Traits::getRegName(CallDest->getRegNum()); |
| 596 Constant *CallTarget = Ctx->getConstantExternSym(H_getIP_prefix + RegName); |
| 597 Context.insert<Traits::Insts::Call>(CallDest, CallTarget); |
| 598 // Insert a new version of InstX86GetIP. |
| 599 Context.insert<Traits::Insts::GetIP>(CallDest); |
| 600 // Spill the register to its home stack location if necessary. |
| 601 if (!Dest->hasReg()) { |
| 602 _mov(Dest, CallDest); |
| 603 } |
| 604 } |
| 605 |
| 558 const VarList &Args = Func->getArgs(); | 606 const VarList &Args = Func->getArgs(); |
| 559 size_t InArgsSizeBytes = 0; | 607 size_t InArgsSizeBytes = 0; |
| 560 unsigned NumXmmArgs = 0; | 608 unsigned NumXmmArgs = 0; |
| 561 for (Variable *Arg : Args) { | 609 for (Variable *Arg : Args) { |
| 562 // Skip arguments passed in registers. | 610 // Skip arguments passed in registers. |
| 563 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { | 611 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { |
| 564 ++NumXmmArgs; | 612 ++NumXmmArgs; |
| 565 continue; | 613 continue; |
| 566 } | 614 } |
| 567 // For esp-based frames where the allocas are done outside the prolog, the | 615 // For esp-based frames where the allocas are done outside the prolog, the |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 Context.insert<InstFakeUse>(RetValue); | 736 Context.insert<InstFakeUse>(RetValue); |
| 689 } | 737 } |
| 690 RI->setDeleted(); | 738 RI->setDeleted(); |
| 691 } | 739 } |
| 692 | 740 |
| 693 void TargetX8632::emitJumpTable(const Cfg *Func, | 741 void TargetX8632::emitJumpTable(const Cfg *Func, |
| 694 const InstJumpTable *JumpTable) const { | 742 const InstJumpTable *JumpTable) const { |
| 695 if (!BuildDefs::dump()) | 743 if (!BuildDefs::dump()) |
| 696 return; | 744 return; |
| 697 Ostream &Str = Ctx->getStrEmit(); | 745 Ostream &Str = Ctx->getStrEmit(); |
| 698 IceString MangledName = Ctx->mangleName(Func->getFunctionName()); | 746 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); |
| 699 Str << "\t.section\t.rodata." << MangledName | 747 const IceString MangledName = Ctx->mangleName(Func->getFunctionName()); |
| 748 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; |
| 749 Str << "\t.section\t" << Prefix << MangledName |
| 700 << "$jumptable,\"a\",@progbits\n"; | 750 << "$jumptable,\"a\",@progbits\n"; |
| 701 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 751 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
| 702 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; | 752 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; |
| 703 | 753 |
| 704 // On X8632 pointers are 32-bit hence the use of .long | 754 // On X8632 pointers are 32-bit hence the use of .long |
| 705 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) | 755 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) |
| 706 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); | 756 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); |
| 707 Str << "\n"; | 757 Str << "\n"; |
| 708 } | 758 } |
| 709 | 759 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); | 898 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); |
| 849 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); | 899 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); |
| 850 | 900 |
| 851 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 901 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
| 852 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 902 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
| 853 } break; | 903 } break; |
| 854 } | 904 } |
| 855 } | 905 } |
| 856 | 906 |
| 857 void TargetDataX8632::lowerJumpTables() { | 907 void TargetDataX8632::lowerJumpTables() { |
| 908 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); |
| 858 switch (Ctx->getFlags().getOutFileType()) { | 909 switch (Ctx->getFlags().getOutFileType()) { |
| 859 case FT_Elf: { | 910 case FT_Elf: { |
| 860 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 911 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
| 861 for (const JumpTableData &JT : Ctx->getJumpTables()) | 912 for (const JumpTableData &JT : Ctx->getJumpTables()) |
| 862 Writer->writeJumpTable(JT, TargetX8632::Traits::RelFixup); | 913 Writer->writeJumpTable(JT, TargetX8632::Traits::FK_Abs, IsPIC); |
| 863 } break; | 914 } break; |
| 864 case FT_Asm: | 915 case FT_Asm: |
| 865 // Already emitted from Cfg | 916 // Already emitted from Cfg |
| 866 break; | 917 break; |
| 867 case FT_Iasm: { | 918 case FT_Iasm: { |
| 868 if (!BuildDefs::dump()) | 919 if (!BuildDefs::dump()) |
| 869 return; | 920 return; |
| 870 Ostream &Str = Ctx->getStrEmit(); | 921 Ostream &Str = Ctx->getStrEmit(); |
| 922 const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; |
| 871 for (const JumpTableData &JT : Ctx->getJumpTables()) { | 923 for (const JumpTableData &JT : Ctx->getJumpTables()) { |
| 872 Str << "\t.section\t.rodata." << JT.getFunctionName() | 924 Str << "\t.section\t" << Prefix << JT.getFunctionName() |
| 873 << "$jumptable,\"a\",@progbits\n"; | 925 << "$jumptable,\"a\",@progbits\n"; |
| 874 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 926 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
| 875 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; | 927 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; |
| 876 | 928 |
| 877 // On X8632 pointers are 32-bit hence the use of .long | 929 // On X8632 pointers are 32-bit hence the use of .long |
| 878 for (intptr_t TargetOffset : JT.getTargetOffsets()) | 930 for (intptr_t TargetOffset : JT.getTargetOffsets()) |
| 879 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; | 931 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; |
| 880 Str << "\n"; | 932 Str << "\n"; |
| 881 } | 933 } |
| 882 } break; | 934 } break; |
| 883 } | 935 } |
| 884 } | 936 } |
| 885 | 937 |
| 886 void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars, | 938 void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars, |
| 887 const IceString &SectionSuffix) { | 939 const IceString &SectionSuffix) { |
| 940 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); |
| 888 switch (Ctx->getFlags().getOutFileType()) { | 941 switch (Ctx->getFlags().getOutFileType()) { |
| 889 case FT_Elf: { | 942 case FT_Elf: { |
| 890 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 943 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
| 891 Writer->writeDataSection(Vars, TargetX8632::Traits::RelFixup, | 944 Writer->writeDataSection(Vars, TargetX8632::Traits::FK_Abs, SectionSuffix, |
| 892 SectionSuffix); | 945 IsPIC); |
| 893 } break; | 946 } break; |
| 894 case FT_Asm: | 947 case FT_Asm: |
| 895 case FT_Iasm: { | 948 case FT_Iasm: { |
| 896 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); | 949 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); |
| 897 OstreamLocker L(Ctx); | 950 OstreamLocker L(Ctx); |
| 898 for (const VariableDeclaration *Var : Vars) { | 951 for (const VariableDeclaration *Var : Vars) { |
| 899 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 952 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
| 900 emitGlobal(*Var, SectionSuffix); | 953 emitGlobal(*Var, SectionSuffix); |
| 901 } | 954 } |
| 902 } | 955 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 #define X(tag, sizeLog2, align, elts, elty, str) \ | 1059 #define X(tag, sizeLog2, align, elts, elty, str) \ |
| 1007 static_assert(_table1_##tag == _table2_##tag, \ | 1060 static_assert(_table1_##tag == _table2_##tag, \ |
| 1008 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 1061 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
| 1009 ICETYPE_TABLE | 1062 ICETYPE_TABLE |
| 1010 #undef X | 1063 #undef X |
| 1011 } // end of namespace dummy3 | 1064 } // end of namespace dummy3 |
| 1012 } // end of anonymous namespace | 1065 } // end of anonymous namespace |
| 1013 | 1066 |
| 1014 } // end of namespace X8632 | 1067 } // end of namespace X8632 |
| 1015 } // end of namespace Ice | 1068 } // end of namespace Ice |
| OLD | NEW |