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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 | 92 |
93 template <> | 93 template <> |
94 std::array<llvm::SmallBitVector, | 94 std::array<llvm::SmallBitVector, |
95 TargetX86Base<TargetX8632>::Traits::RegisterSet::Reg_NUM> | 95 TargetX86Base<TargetX8632>::Traits::RegisterSet::Reg_NUM> |
96 TargetX86Base<TargetX8632>::RegisterAliases = {{}}; | 96 TargetX86Base<TargetX8632>::RegisterAliases = {{}}; |
97 | 97 |
98 template <> | 98 template <> |
99 llvm::SmallBitVector | 99 llvm::SmallBitVector |
100 TargetX86Base<TargetX8632>::ScratchRegs = llvm::SmallBitVector(); | 100 TargetX86Base<TargetX8632>::ScratchRegs = llvm::SmallBitVector(); |
101 | 101 |
102 template <> | |
103 FixupKind TargetX86Base<TargetX8632>::PcRelFixup = | |
John
2015/12/22 15:44:38
I know this will be painful to change, but pic(k)
Jim Stichnoth
2015/12/28 07:54:07
New naming scheme described in a previous comment.
| |
104 TargetX86Base<TargetX8632>::Traits::FixupKindPcRel; | |
105 | |
106 template <> | |
107 FixupKind TargetX86Base<TargetX8632>::RelFixup = | |
108 TargetX86Base<TargetX8632>::Traits::FixupKindAbs; | |
109 | |
102 } // end of namespace X86Internal | 110 } // end of namespace X86Internal |
103 | 111 |
104 //------------------------------------------------------------------------------ | 112 //------------------------------------------------------------------------------ |
105 // __ ______ __ __ ______ ______ __ __ __ ______ | 113 // __ ______ __ __ ______ ______ __ __ __ ______ |
106 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ | 114 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ |
107 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ | 115 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ |
108 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ | 116 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ |
109 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ | 117 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ |
110 // | 118 // |
111 //------------------------------------------------------------------------------ | 119 //------------------------------------------------------------------------------ |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 case IceType_v8i1: | 230 case IceType_v8i1: |
223 case IceType_v16i1: | 231 case IceType_v16i1: |
224 case IceType_v16i8: | 232 case IceType_v16i8: |
225 case IceType_v8i16: | 233 case IceType_v8i16: |
226 case IceType_v4i32: | 234 case IceType_v4i32: |
227 case IceType_v4f32: | 235 case IceType_v4f32: |
228 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); | 236 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); |
229 break; | 237 break; |
230 } | 238 } |
231 } | 239 } |
232 Operand *CallTarget = legalize(Instr->getCallTarget()); | 240 Operand *CallTarget = |
241 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); | |
233 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 242 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
234 if (NeedSandboxing) { | 243 if (NeedSandboxing) { |
235 if (llvm::isa<Constant>(CallTarget)) { | 244 if (llvm::isa<Constant>(CallTarget)) { |
236 _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 245 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
237 } else { | 246 } else { |
238 Variable *CallTargetVar = nullptr; | 247 Variable *CallTargetVar = nullptr; |
239 _mov(CallTargetVar, CallTarget); | 248 _mov(CallTargetVar, CallTarget); |
240 _bundle_lock(InstBundleLock::Opt_AlignToEnd); | 249 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
241 const SizeT BundleSize = | 250 const SizeT BundleSize = |
242 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 251 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 // registers (as a side effect, this gives variables a second chance at | 405 // registers (as a side effect, this gives variables a second chance at |
397 // physical register assignment). | 406 // physical register assignment). |
398 // | 407 // |
399 // A middle ground approach is to leverage sparsity and allocate one block of | 408 // A middle ground approach is to leverage sparsity and allocate one block of |
400 // space on the frame for globals (variables with multi-block lifetime), and | 409 // space on the frame for globals (variables with multi-block lifetime), and |
401 // one block to share for locals (single-block lifetime). | 410 // one block to share for locals (single-block lifetime). |
402 | 411 |
403 Context.init(Node); | 412 Context.init(Node); |
404 Context.setInsertPoint(Context.getCur()); | 413 Context.setInsertPoint(Context.getCur()); |
405 | 414 |
415 // If there is a non-deleted InstX86GetIP instruction, we need to move it to | |
416 // the point after the stack frame has stabilized but before | |
417 // register-allocated in-args are copied into their home registers. | |
418 X86Internal::InstX86GetIP<TargetX8632> *GetIPInst = nullptr; | |
419 if (Ctx->getFlags().getUseNonsfi()) { | |
420 for (Inst &Instr : Node->getInsts()) { | |
421 if (auto *GetIP = | |
422 llvm::dyn_cast<X86Internal::InstX86GetIP<TargetX8632>>(&Instr)) { | |
423 if (!Instr.isDeleted()) | |
424 GetIPInst = GetIP; | |
425 break; | |
426 } | |
427 } | |
428 } | |
429 | |
406 llvm::SmallBitVector CalleeSaves = | 430 llvm::SmallBitVector CalleeSaves = |
407 getRegisterSet(RegSet_CalleeSave, RegSet_None); | 431 getRegisterSet(RegSet_CalleeSave, RegSet_None); |
408 RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); | 432 RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); |
409 VarList SortedSpilledVariables, VariablesLinkedToSpillSlots; | 433 VarList SortedSpilledVariables, VariablesLinkedToSpillSlots; |
410 size_t GlobalsSize = 0; | 434 size_t GlobalsSize = 0; |
411 // If there is a separate locals area, this represents that area. Otherwise | 435 // If there is a separate locals area, this represents that area. Otherwise |
412 // it counts any variable not counted by GlobalsSize. | 436 // it counts any variable not counted by GlobalsSize. |
413 SpillAreaSizeBytes = 0; | 437 SpillAreaSizeBytes = 0; |
414 // If there is a separate locals area, this specifies the alignment for it. | 438 // If there is a separate locals area, this specifies the alignment for it. |
415 uint32_t LocalsSlotsAlignmentBytes = 0; | 439 uint32_t LocalsSlotsAlignmentBytes = 0; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
537 | 561 |
538 // Fill in stack offsets for stack args, and copy args into registers for | 562 // Fill in stack offsets for stack args, and copy args into registers for |
539 // those that were register-allocated. Args are pushed right to left, so | 563 // those that were register-allocated. Args are pushed right to left, so |
540 // Arg[0] is closest to the stack/frame pointer. | 564 // Arg[0] is closest to the stack/frame pointer. |
541 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); | 565 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); |
542 size_t BasicFrameOffset = | 566 size_t BasicFrameOffset = |
543 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES; | 567 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES; |
544 if (!IsEbpBasedFrame) | 568 if (!IsEbpBasedFrame) |
545 BasicFrameOffset += SpillAreaSizeBytes; | 569 BasicFrameOffset += SpillAreaSizeBytes; |
546 | 570 |
571 // Delete any existing InstX86GetIP instruction and reinsert it here. Also, | |
572 // insert the call to the helper function and the spill to the stack, to | |
573 // simplify emission. | |
574 if (GetIPInst) { | |
575 GetIPInst->setDeleted(); | |
576 Variable *Dest = GetIPInst->getDest(); | |
577 Variable *CallDest = | |
578 Dest->hasReg() ? Dest | |
579 : getPhysicalRegister(Traits::RegisterSet::Reg_eax); | |
580 // Call the getIP_<reg> helper. | |
581 IceString RegName = Traits::getRegName(CallDest->getRegNum()); | |
582 Constant *CallTarget = Ctx->getConstantExternSym(H_getIP_prefix + RegName); | |
583 Context.insert<Traits::Insts::Call>(CallDest, CallTarget); | |
584 // Insert a new version of InstX86GetIP. | |
585 Context.insert<X86Internal::InstX86GetIP<TargetX8632>>(CallDest); | |
586 // Spill the register to its home stack location if necessary. | |
587 if (!Dest->hasReg()) { | |
588 _mov(Dest, CallDest); | |
589 } | |
590 } | |
591 | |
547 const VarList &Args = Func->getArgs(); | 592 const VarList &Args = Func->getArgs(); |
548 size_t InArgsSizeBytes = 0; | 593 size_t InArgsSizeBytes = 0; |
549 unsigned NumXmmArgs = 0; | 594 unsigned NumXmmArgs = 0; |
550 for (Variable *Arg : Args) { | 595 for (Variable *Arg : Args) { |
551 // Skip arguments passed in registers. | 596 // Skip arguments passed in registers. |
552 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { | 597 if (isVectorType(Arg->getType()) && NumXmmArgs < Traits::X86_MAX_XMM_ARGS) { |
553 ++NumXmmArgs; | 598 ++NumXmmArgs; |
554 continue; | 599 continue; |
555 } | 600 } |
556 // For esp-based frames where the allocas are done outside the prolog, the | 601 // 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... | |
677 Context.insert<InstFakeUse>(RetValue); | 722 Context.insert<InstFakeUse>(RetValue); |
678 } | 723 } |
679 RI->setDeleted(); | 724 RI->setDeleted(); |
680 } | 725 } |
681 | 726 |
682 void TargetX8632::emitJumpTable(const Cfg *Func, | 727 void TargetX8632::emitJumpTable(const Cfg *Func, |
683 const InstJumpTable *JumpTable) const { | 728 const InstJumpTable *JumpTable) const { |
684 if (!BuildDefs::dump()) | 729 if (!BuildDefs::dump()) |
685 return; | 730 return; |
686 Ostream &Str = Ctx->getStrEmit(); | 731 Ostream &Str = Ctx->getStrEmit(); |
687 IceString MangledName = Ctx->mangleName(Func->getFunctionName()); | 732 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); |
688 Str << "\t.section\t.rodata." << MangledName | 733 const IceString MangledName = Ctx->mangleName(Func->getFunctionName()); |
734 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; | |
735 Str << "\t.section\t" << Prefix << MangledName | |
689 << "$jumptable,\"a\",@progbits\n"; | 736 << "$jumptable,\"a\",@progbits\n"; |
690 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 737 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
691 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; | 738 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; |
692 | 739 |
693 // On X8632 pointers are 32-bit hence the use of .long | 740 // On X8632 pointers are 32-bit hence the use of .long |
694 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) | 741 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) |
695 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); | 742 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); |
696 Str << "\n"; | 743 Str << "\n"; |
697 } | 744 } |
698 | 745 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
837 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); | 884 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); |
838 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); | 885 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); |
839 | 886 |
840 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 887 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
841 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 888 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
842 } break; | 889 } break; |
843 } | 890 } |
844 } | 891 } |
845 | 892 |
846 void TargetDataX8632::lowerJumpTables() { | 893 void TargetDataX8632::lowerJumpTables() { |
894 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | |
847 switch (Ctx->getFlags().getOutFileType()) { | 895 switch (Ctx->getFlags().getOutFileType()) { |
848 case FT_Elf: { | 896 case FT_Elf: { |
849 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 897 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
850 for (const JumpTableData &JT : Ctx->getJumpTables()) | 898 for (const JumpTableData &JT : Ctx->getJumpTables()) |
851 Writer->writeJumpTable(JT, TargetX8632::Traits::RelFixup); | 899 Writer->writeJumpTable(JT, TargetX8632::Traits::FixupKindAbs, IsPIC); |
852 } break; | 900 } break; |
853 case FT_Asm: | 901 case FT_Asm: |
854 // Already emitted from Cfg | 902 // Already emitted from Cfg |
855 break; | 903 break; |
856 case FT_Iasm: { | 904 case FT_Iasm: { |
857 if (!BuildDefs::dump()) | 905 if (!BuildDefs::dump()) |
858 return; | 906 return; |
859 Ostream &Str = Ctx->getStrEmit(); | 907 Ostream &Str = Ctx->getStrEmit(); |
908 const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; | |
860 for (const JumpTableData &JT : Ctx->getJumpTables()) { | 909 for (const JumpTableData &JT : Ctx->getJumpTables()) { |
861 Str << "\t.section\t.rodata." << JT.getFunctionName() | 910 Str << "\t.section\t" << Prefix << JT.getFunctionName() |
862 << "$jumptable,\"a\",@progbits\n"; | 911 << "$jumptable,\"a\",@progbits\n"; |
863 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 912 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
864 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; | 913 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; |
865 | 914 |
866 // On X8632 pointers are 32-bit hence the use of .long | 915 // On X8632 pointers are 32-bit hence the use of .long |
867 for (intptr_t TargetOffset : JT.getTargetOffsets()) | 916 for (intptr_t TargetOffset : JT.getTargetOffsets()) |
868 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; | 917 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; |
869 Str << "\n"; | 918 Str << "\n"; |
870 } | 919 } |
871 } break; | 920 } break; |
872 } | 921 } |
873 } | 922 } |
874 | 923 |
875 void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars, | 924 void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars, |
876 const IceString &SectionSuffix) { | 925 const IceString &SectionSuffix) { |
926 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | |
877 switch (Ctx->getFlags().getOutFileType()) { | 927 switch (Ctx->getFlags().getOutFileType()) { |
878 case FT_Elf: { | 928 case FT_Elf: { |
879 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 929 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
880 Writer->writeDataSection(Vars, TargetX8632::Traits::RelFixup, | 930 Writer->writeDataSection(Vars, TargetX8632::Traits::FixupKindAbs, |
881 SectionSuffix); | 931 SectionSuffix, IsPIC); |
882 } break; | 932 } break; |
883 case FT_Asm: | 933 case FT_Asm: |
884 case FT_Iasm: { | 934 case FT_Iasm: { |
885 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); | 935 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); |
886 OstreamLocker L(Ctx); | 936 OstreamLocker L(Ctx); |
887 for (const VariableDeclaration *Var : Vars) { | 937 for (const VariableDeclaration *Var : Vars) { |
888 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 938 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
889 emitGlobal(*Var, SectionSuffix); | 939 emitGlobal(*Var, SectionSuffix); |
890 } | 940 } |
891 } | 941 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
994 // case the high-level table has extra entries. | 1044 // case the high-level table has extra entries. |
995 #define X(tag, sizeLog2, align, elts, elty, str) \ | 1045 #define X(tag, sizeLog2, align, elts, elty, str) \ |
996 static_assert(_table1_##tag == _table2_##tag, \ | 1046 static_assert(_table1_##tag == _table2_##tag, \ |
997 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 1047 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
998 ICETYPE_TABLE | 1048 ICETYPE_TABLE |
999 #undef X | 1049 #undef X |
1000 } // end of namespace dummy3 | 1050 } // end of namespace dummy3 |
1001 } // end of anonymous namespace | 1051 } // end of anonymous namespace |
1002 | 1052 |
1003 } // end of namespace Ice | 1053 } // end of namespace Ice |
OLD | NEW |