Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1506653002: Subzero: Add Non-SFI support for x86-32. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Refactor the link commands Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 =
104 TargetX86Base<TargetX8632>::Traits::FK_PcRel;
105
106 template <>
107 FixupKind TargetX86Base<TargetX8632>::AbsFixup =
108 TargetX86Base<TargetX8632>::Traits::FK_Abs;
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
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
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
John 2016/01/04 21:33:51 Can you move this block closer to where GetIpInst
Jim Stichnoth 2016/01/04 23:32:12 Moved the def and use closer together - with a com
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;
John 2016/01/04 21:33:51 whenever you add an X86 instruction, add it to the
Jim Stichnoth 2016/01/04 23:32:12 Done.
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
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
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
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::FK_Abs, 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::FK_Abs, SectionSuffix,
881 SectionSuffix); 931 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698