| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- 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 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i) | 369 for (size_t i = 0; i < TypeToRegisterSet.size(); ++i) |
| 370 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; | 370 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; |
| 371 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM, | 371 filterTypeToRegisterSet(Ctx, Traits::RegisterSet::Reg_NUM, |
| 372 TypeToRegisterSet.data(), TypeToRegisterSet.size(), | 372 TypeToRegisterSet.data(), TypeToRegisterSet.size(), |
| 373 Traits::getRegName, getRegClassName); | 373 Traits::getRegName, getRegClassName); |
| 374 PcRelFixup = Traits::FK_PcRel; | 374 PcRelFixup = Traits::FK_PcRel; |
| 375 AbsFixup = | 375 AbsFixup = |
| 376 Ctx->getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs; | 376 Ctx->getFlags().getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs; |
| 377 } | 377 } |
| 378 | 378 |
| 379 template <typename TraitsType> |
| 380 bool TargetX86Base<TraitsType>::shouldBePooled(const Constant *C) { |
| 381 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(C)) { |
| 382 return !Utils::isPositiveZero(ConstFloat->getValue()); |
| 383 } |
| 384 if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(C)) { |
| 385 return !Utils::isPositiveZero(ConstDouble->getValue()); |
| 386 } |
| 387 if (GlobalContext::getFlags().getRandomizeAndPoolImmediatesOption() != |
| 388 RPI_Pool) { |
| 389 return false; |
| 390 } |
| 391 return C->shouldBeRandomizedOrPooled(); |
| 392 } |
| 393 |
| 379 template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() { | 394 template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() { |
| 380 TimerMarker T(TimerStack::TT_O2, Func); | 395 TimerMarker T(TimerStack::TT_O2, Func); |
| 381 | 396 |
| 382 if (SandboxingType != ST_None) { | 397 if (SandboxingType != ST_None) { |
| 383 initRebasePtr(); | 398 initRebasePtr(); |
| 384 } | 399 } |
| 385 | 400 |
| 386 genTargetHelperCalls(); | 401 genTargetHelperCalls(); |
| 387 Func->dump("After target helper call insertion"); | 402 Func->dump("After target helper call insertion"); |
| 388 | 403 |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 // liveness validation errors for saving callee-save registers. | 863 // liveness validation errors for saving callee-save registers. |
| 849 Func->addImplicitArg(Reg); | 864 Func->addImplicitArg(Reg); |
| 850 // Don't bother tracking the live range of a named physical register. | 865 // Don't bother tracking the live range of a named physical register. |
| 851 Reg->setIgnoreLiveness(); | 866 Reg->setIgnoreLiveness(); |
| 852 } | 867 } |
| 853 assert(Traits::getGprForType(Ty, RegNum) == RegNum); | 868 assert(Traits::getGprForType(Ty, RegNum) == RegNum); |
| 854 return Reg; | 869 return Reg; |
| 855 } | 870 } |
| 856 | 871 |
| 857 template <typename TraitsType> | 872 template <typename TraitsType> |
| 858 IceString TargetX86Base<TraitsType>::getRegName(RegNumT RegNum, Type Ty) const { | 873 const char *TargetX86Base<TraitsType>::getRegName(RegNumT RegNum, |
| 874 Type Ty) const { |
| 859 return Traits::getRegName(Traits::getGprForType(Ty, RegNum)); | 875 return Traits::getRegName(Traits::getGprForType(Ty, RegNum)); |
| 860 } | 876 } |
| 861 | 877 |
| 862 template <typename TraitsType> | 878 template <typename TraitsType> |
| 863 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { | 879 void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { |
| 864 if (!BuildDefs::dump()) | 880 if (!BuildDefs::dump()) |
| 865 return; | 881 return; |
| 866 Ostream &Str = Ctx->getStrEmit(); | 882 Ostream &Str = Ctx->getStrEmit(); |
| 867 if (Var->hasReg()) { | 883 if (Var->hasReg()) { |
| 868 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing; | 884 const bool Is64BitSandboxing = Traits::Is64Bit && NeedSandboxing; |
| (...skipping 4992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5861 assert(Traits::Is64Bit); | 5877 assert(Traits::Is64Bit); |
| 5862 _mov(Index, RangeIndex); // trunc | 5878 _mov(Index, RangeIndex); // trunc |
| 5863 } else { | 5879 } else { |
| 5864 _movzx(Index, RangeIndex); | 5880 _movzx(Index, RangeIndex); |
| 5865 } | 5881 } |
| 5866 } else { | 5882 } else { |
| 5867 Index = legalizeToReg(RangeIndex); | 5883 Index = legalizeToReg(RangeIndex); |
| 5868 } | 5884 } |
| 5869 | 5885 |
| 5870 constexpr RelocOffsetT RelocOffset = 0; | 5886 constexpr RelocOffsetT RelocOffset = 0; |
| 5871 const IceString &FunctionName = Func->getFunctionName(); | 5887 GlobalString FunctionName = Func->getFunctionName(); |
| 5872 constexpr Variable *NoBase = nullptr; | 5888 constexpr Variable *NoBase = nullptr; |
| 5873 Constant *Offset = Ctx->getConstantSym( | 5889 auto JTName = GlobalString::createWithString( |
| 5874 RelocOffset, InstJumpTable::makeName(FunctionName, JumpTable->getId())); | 5890 Ctx, InstJumpTable::makeName(FunctionName, JumpTable->getId())); |
| 5891 Constant *Offset = Ctx->getConstantSym(RelocOffset, JTName); |
| 5875 uint16_t Shift = typeWidthInBytesLog2(PointerType); | 5892 uint16_t Shift = typeWidthInBytesLog2(PointerType); |
| 5876 constexpr auto Segment = X86OperandMem::SegmentRegisters::DefaultSegment; | 5893 constexpr auto Segment = X86OperandMem::SegmentRegisters::DefaultSegment; |
| 5877 | 5894 |
| 5878 Variable *Target = nullptr; | 5895 Variable *Target = nullptr; |
| 5879 if (Traits::Is64Bit && NeedSandboxing) { | 5896 if (Traits::Is64Bit && NeedSandboxing) { |
| 5880 assert(Index != nullptr && Index->getType() == IceType_i32); | 5897 assert(Index != nullptr && Index->getType() == IceType_i32); |
| 5881 } | 5898 } |
| 5882 auto *TargetInMemory = X86OperandMem::create(Func, PointerType, NoBase, | 5899 auto *TargetInMemory = X86OperandMem::create(Func, PointerType, NoBase, |
| 5883 Offset, Index, Shift, Segment); | 5900 Offset, Index, Shift, Segment); |
| 5884 _mov(Target, TargetInMemory); | 5901 _mov(Target, TargetInMemory); |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6811 // Convert a scalar floating point constant into an explicit memory | 6828 // Convert a scalar floating point constant into an explicit memory |
| 6812 // operand. | 6829 // operand. |
| 6813 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(Const)) { | 6830 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(Const)) { |
| 6814 if (Utils::isPositiveZero(ConstFloat->getValue())) | 6831 if (Utils::isPositiveZero(ConstFloat->getValue())) |
| 6815 return makeZeroedRegister(Ty, RegNum); | 6832 return makeZeroedRegister(Ty, RegNum); |
| 6816 } else if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(Const)) { | 6833 } else if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(Const)) { |
| 6817 if (Utils::isPositiveZero(ConstDouble->getValue())) | 6834 if (Utils::isPositiveZero(ConstDouble->getValue())) |
| 6818 return makeZeroedRegister(Ty, RegNum); | 6835 return makeZeroedRegister(Ty, RegNum); |
| 6819 } | 6836 } |
| 6820 | 6837 |
| 6821 std::string Buffer; | 6838 auto *CFrom = llvm::cast<Constant>(From); |
| 6822 llvm::raw_string_ostream StrBuf(Buffer); | 6839 assert(CFrom->getShouldBePooled()); |
| 6823 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf); | 6840 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName()); |
| 6824 llvm::cast<Constant>(From)->setShouldBePooled(true); | |
| 6825 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str()); | |
| 6826 auto *Mem = X86OperandMem::create(Func, Ty, nullptr, Offset); | 6841 auto *Mem = X86OperandMem::create(Func, Ty, nullptr, Offset); |
| 6827 From = Mem; | 6842 From = Mem; |
| 6828 } | 6843 } |
| 6829 | 6844 |
| 6830 bool NeedsReg = false; | 6845 bool NeedsReg = false; |
| 6831 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) | 6846 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) |
| 6832 // Immediate specifically not allowed. | 6847 // Immediate specifically not allowed. |
| 6833 NeedsReg = true; | 6848 NeedsReg = true; |
| 6834 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) | 6849 if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty)) |
| 6835 // On x86, FP constants are lowered to mem operands. | 6850 // On x86, FP constants are lowered to mem operands. |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7032 Ostream &Str = Ctx->getStrEmit(); | 7047 Ostream &Str = Ctx->getStrEmit(); |
| 7033 Str << "$" << C->getValue(); | 7048 Str << "$" << C->getValue(); |
| 7034 } | 7049 } |
| 7035 } | 7050 } |
| 7036 | 7051 |
| 7037 template <typename TraitsType> | 7052 template <typename TraitsType> |
| 7038 void TargetX86Base<TraitsType>::emit(const ConstantFloat *C) const { | 7053 void TargetX86Base<TraitsType>::emit(const ConstantFloat *C) const { |
| 7039 if (!BuildDefs::dump()) | 7054 if (!BuildDefs::dump()) |
| 7040 return; | 7055 return; |
| 7041 Ostream &Str = Ctx->getStrEmit(); | 7056 Ostream &Str = Ctx->getStrEmit(); |
| 7042 C->emitPoolLabel(Str); | 7057 Str << C->getLabelName(); |
| 7043 } | 7058 } |
| 7044 | 7059 |
| 7045 template <typename TraitsType> | 7060 template <typename TraitsType> |
| 7046 void TargetX86Base<TraitsType>::emit(const ConstantDouble *C) const { | 7061 void TargetX86Base<TraitsType>::emit(const ConstantDouble *C) const { |
| 7047 if (!BuildDefs::dump()) | 7062 if (!BuildDefs::dump()) |
| 7048 return; | 7063 return; |
| 7049 Ostream &Str = Ctx->getStrEmit(); | 7064 Ostream &Str = Ctx->getStrEmit(); |
| 7050 C->emitPoolLabel(Str); | 7065 Str << C->getLabelName(); |
| 7051 } | 7066 } |
| 7052 | 7067 |
| 7053 template <typename TraitsType> | 7068 template <typename TraitsType> |
| 7054 void TargetX86Base<TraitsType>::emit(const ConstantUndef *) const { | 7069 void TargetX86Base<TraitsType>::emit(const ConstantUndef *) const { |
| 7055 llvm::report_fatal_error("undef value encountered by emitter."); | 7070 llvm::report_fatal_error("undef value encountered by emitter."); |
| 7056 } | 7071 } |
| 7057 | 7072 |
| 7058 template <class Machine> | 7073 template <class Machine> |
| 7059 void TargetX86Base<Machine>::emit(const ConstantRelocatable *C) const { | 7074 void TargetX86Base<Machine>::emit(const ConstantRelocatable *C) const { |
| 7060 if (!BuildDefs::dump()) | 7075 if (!BuildDefs::dump()) |
| 7061 return; | 7076 return; |
| 7062 assert(!Ctx->getFlags().getUseNonsfi() || C->getName() == GlobalOffsetTable); | 7077 assert(!Ctx->getFlags().getUseNonsfi() || |
| 7078 C->getName().toString() == GlobalOffsetTable); |
| 7063 Ostream &Str = Ctx->getStrEmit(); | 7079 Ostream &Str = Ctx->getStrEmit(); |
| 7064 Str << "$"; | 7080 Str << "$"; |
| 7065 emitWithoutPrefix(C); | 7081 emitWithoutPrefix(C); |
| 7066 } | 7082 } |
| 7067 | 7083 |
| 7068 /// Randomize or pool an Immediate. | 7084 /// Randomize or pool an Immediate. |
| 7069 template <typename TraitsType> | 7085 template <typename TraitsType> |
| 7070 Operand * | 7086 Operand * |
| 7071 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, | 7087 TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate, |
| 7072 RegNumT RegNum) { | 7088 RegNumT RegNum) { |
| 7073 assert(llvm::isa<ConstantInteger32>(Immediate) || | 7089 assert(llvm::isa<ConstantInteger32>(Immediate) || |
| 7074 llvm::isa<ConstantRelocatable>(Immediate)); | 7090 llvm::isa<ConstantRelocatable>(Immediate)); |
| 7075 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || | 7091 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None || |
| 7076 RandomizationPoolingPaused == true) { | 7092 RandomizationPoolingPaused == true) { |
| 7077 // Immediates randomization/pooling off or paused | 7093 // Immediates randomization/pooling off or paused |
| 7078 return Immediate; | 7094 return Immediate; |
| 7079 } | 7095 } |
| 7080 | 7096 |
| 7081 if (Traits::Is64Bit && NeedSandboxing) { | 7097 if (Traits::Is64Bit && NeedSandboxing) { |
| 7082 // Immediate randomization/pooling is currently disabled for x86-64 | 7098 // Immediate randomization/pooling is currently disabled for x86-64 |
| 7083 // sandboxing for it could generate invalid memory operands. | 7099 // sandboxing for it could generate invalid memory operands. |
| 7084 assert(false && | 7100 assert(false && |
| 7085 "Constant pooling/randomization is disabled for x8664 sandbox."); | 7101 "Constant pooling/randomization is disabled for x8664 sandbox."); |
| 7086 return Immediate; | 7102 return Immediate; |
| 7087 } | 7103 } |
| 7088 | 7104 |
| 7089 if (!Immediate->shouldBeRandomizedOrPooled(Ctx)) { | 7105 if (!Immediate->shouldBeRandomizedOrPooled()) { |
| 7090 // the constant Immediate is not eligible for blinding/pooling | 7106 // the constant Immediate is not eligible for blinding/pooling |
| 7091 return Immediate; | 7107 return Immediate; |
| 7092 } | 7108 } |
| 7093 Ctx->statsUpdateRPImms(); | 7109 Ctx->statsUpdateRPImms(); |
| 7094 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { | 7110 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { |
| 7095 default: | 7111 default: |
| 7096 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); | 7112 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); |
| 7097 case RPI_Randomize: { | 7113 case RPI_Randomize: { |
| 7098 // blind the constant | 7114 // blind the constant |
| 7099 // FROM: | 7115 // FROM: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 7122 return TruncReg; | 7138 return TruncReg; |
| 7123 } | 7139 } |
| 7124 case RPI_Pool: { | 7140 case RPI_Pool: { |
| 7125 // pool the constant | 7141 // pool the constant |
| 7126 // FROM: | 7142 // FROM: |
| 7127 // imm | 7143 // imm |
| 7128 // TO: | 7144 // TO: |
| 7129 // insert: mov $label, Reg | 7145 // insert: mov $label, Reg |
| 7130 // => Reg | 7146 // => Reg |
| 7131 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool); | 7147 assert(Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Pool); |
| 7132 Immediate->setShouldBePooled(true); | 7148 assert(Immediate->getShouldBePooled()); |
| 7133 // if we have already assigned a phy register, we must come from | 7149 // if we have already assigned a phy register, we must come from |
| 7134 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse the | 7150 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse the |
| 7135 // assigned register as this assignment is that start of its use-def | 7151 // assigned register as this assignment is that start of its use-def |
| 7136 // chain. So we add RegNum argument here. | 7152 // chain. So we add RegNum argument here. |
| 7137 Variable *Reg = makeReg(Immediate->getType(), RegNum); | 7153 Variable *Reg = makeReg(Immediate->getType(), RegNum); |
| 7138 IceString Label; | |
| 7139 llvm::raw_string_ostream Label_stream(Label); | |
| 7140 Immediate->emitPoolLabel(Label_stream); | |
| 7141 constexpr RelocOffsetT Offset = 0; | 7154 constexpr RelocOffsetT Offset = 0; |
| 7142 Constant *Symbol = Ctx->getConstantSym(Offset, Label_stream.str()); | 7155 Constant *Symbol = Ctx->getConstantSym(Offset, Immediate->getLabelName()); |
| 7143 constexpr Variable *NoBase = nullptr; | 7156 constexpr Variable *NoBase = nullptr; |
| 7144 X86OperandMem *MemOperand = | 7157 X86OperandMem *MemOperand = |
| 7145 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); | 7158 X86OperandMem::create(Func, Immediate->getType(), NoBase, Symbol); |
| 7146 _mov(Reg, MemOperand); | 7159 _mov(Reg, MemOperand); |
| 7147 return Reg; | 7160 return Reg; |
| 7148 } | 7161 } |
| 7149 } | 7162 } |
| 7150 } | 7163 } |
| 7151 | 7164 |
| 7152 template <typename TraitsType> | 7165 template <typename TraitsType> |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7172 // again. | 7185 // again. |
| 7173 if (MemOperand->getRandomized()) | 7186 if (MemOperand->getRandomized()) |
| 7174 return MemOperand; | 7187 return MemOperand; |
| 7175 | 7188 |
| 7176 auto *C = llvm::dyn_cast_or_null<Constant>(MemOperand->getOffset()); | 7189 auto *C = llvm::dyn_cast_or_null<Constant>(MemOperand->getOffset()); |
| 7177 | 7190 |
| 7178 if (C == nullptr) { | 7191 if (C == nullptr) { |
| 7179 return MemOperand; | 7192 return MemOperand; |
| 7180 } | 7193 } |
| 7181 | 7194 |
| 7182 if (!C->shouldBeRandomizedOrPooled(Ctx)) { | 7195 if (!C->shouldBeRandomizedOrPooled()) { |
| 7183 return MemOperand; | 7196 return MemOperand; |
| 7184 } | 7197 } |
| 7185 | 7198 |
| 7186 // The offset of this mem operand should be blinded or pooled | 7199 // The offset of this mem operand should be blinded or pooled |
| 7187 Ctx->statsUpdateRPImms(); | 7200 Ctx->statsUpdateRPImms(); |
| 7188 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { | 7201 switch (Ctx->getFlags().getRandomizeAndPoolImmediatesOption()) { |
| 7189 default: | 7202 default: |
| 7190 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); | 7203 llvm::report_fatal_error("Unsupported -randomize-pool-immediates option"); |
| 7191 case RPI_Randomize: { | 7204 case RPI_Randomize: { |
| 7192 // blind the constant offset | 7205 // blind the constant offset |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7233 // =>[RegTemp, index, shift] | 7246 // =>[RegTemp, index, shift] |
| 7234 | 7247 |
| 7235 // Memory operand should never exist as source operands in phi lowering | 7248 // Memory operand should never exist as source operands in phi lowering |
| 7236 // assignments, so there is no need to reuse any registers here. For | 7249 // assignments, so there is no need to reuse any registers here. For |
| 7237 // phi lowering, we should not ask for new physical registers in | 7250 // phi lowering, we should not ask for new physical registers in |
| 7238 // general. However, if we do meet Memory Operand during phi lowering, | 7251 // general. However, if we do meet Memory Operand during phi lowering, |
| 7239 // we should not blind or pool the immediates for now. | 7252 // we should not blind or pool the immediates for now. |
| 7240 if (RegNum.hasValue()) | 7253 if (RegNum.hasValue()) |
| 7241 return MemOperand; | 7254 return MemOperand; |
| 7242 Variable *RegTemp = makeReg(IceType_i32); | 7255 Variable *RegTemp = makeReg(IceType_i32); |
| 7243 IceString Label; | 7256 assert(MemOperand->getOffset()->getShouldBePooled()); |
| 7244 llvm::raw_string_ostream Label_stream(Label); | |
| 7245 MemOperand->getOffset()->emitPoolLabel(Label_stream); | |
| 7246 MemOperand->getOffset()->setShouldBePooled(true); | |
| 7247 constexpr RelocOffsetT SymOffset = 0; | 7257 constexpr RelocOffsetT SymOffset = 0; |
| 7248 Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str()); | 7258 Constant *Symbol = |
| 7259 Ctx->getConstantSym(SymOffset, MemOperand->getOffset()->getLabelName()); |
| 7249 constexpr Variable *NoBase = nullptr; | 7260 constexpr Variable *NoBase = nullptr; |
| 7250 X86OperandMem *SymbolOperand = X86OperandMem::create( | 7261 X86OperandMem *SymbolOperand = X86OperandMem::create( |
| 7251 Func, MemOperand->getOffset()->getType(), NoBase, Symbol); | 7262 Func, MemOperand->getOffset()->getType(), NoBase, Symbol); |
| 7252 _mov(RegTemp, SymbolOperand); | 7263 _mov(RegTemp, SymbolOperand); |
| 7253 // If we have a base variable here, we should add the lea instruction | 7264 // If we have a base variable here, we should add the lea instruction |
| 7254 // to add the value of the base variable to RegTemp. If there is no | 7265 // to add the value of the base variable to RegTemp. If there is no |
| 7255 // base variable, we won't need this lea instruction. | 7266 // base variable, we won't need this lea instruction. |
| 7256 if (MemOperand->getBase()) { | 7267 if (MemOperand->getBase()) { |
| 7257 X86OperandMem *CalculateOperand = X86OperandMem::create( | 7268 X86OperandMem *CalculateOperand = X86OperandMem::create( |
| 7258 Func, MemOperand->getType(), MemOperand->getBase(), nullptr, RegTemp, | 7269 Func, MemOperand->getType(), MemOperand->getBase(), nullptr, RegTemp, |
| 7259 0, MemOperand->getSegmentRegister()); | 7270 0, MemOperand->getSegmentRegister()); |
| 7260 _lea(RegTemp, CalculateOperand); | 7271 _lea(RegTemp, CalculateOperand); |
| 7261 } | 7272 } |
| 7262 X86OperandMem *NewMemOperand = X86OperandMem::create( | 7273 X86OperandMem *NewMemOperand = X86OperandMem::create( |
| 7263 Func, MemOperand->getType(), RegTemp, nullptr, MemOperand->getIndex(), | 7274 Func, MemOperand->getType(), RegTemp, nullptr, MemOperand->getIndex(), |
| 7264 MemOperand->getShift(), MemOperand->getSegmentRegister()); | 7275 MemOperand->getShift(), MemOperand->getSegmentRegister()); |
| 7265 return NewMemOperand; | 7276 return NewMemOperand; |
| 7266 } | 7277 } |
| 7267 } | 7278 } |
| 7268 } | 7279 } |
| 7269 | 7280 |
| 7270 template <typename TraitsType> | 7281 template <typename TraitsType> |
| 7271 void TargetX86Base<TraitsType>::emitJumpTable( | 7282 void TargetX86Base<TraitsType>::emitJumpTable( |
| 7272 const Cfg *Func, const InstJumpTable *JumpTable) const { | 7283 const Cfg *Func, const InstJumpTable *JumpTable) const { |
| 7273 if (!BuildDefs::dump()) | 7284 if (!BuildDefs::dump()) |
| 7274 return; | 7285 return; |
| 7275 Ostream &Str = Ctx->getStrEmit(); | 7286 Ostream &Str = Ctx->getStrEmit(); |
| 7276 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); | 7287 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); |
| 7277 const IceString &FunctionName = Func->getFunctionName(); | 7288 GlobalString FunctionName = Func->getFunctionName(); |
| 7278 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; | 7289 const char *Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; |
| 7279 Str << "\t.section\t" << Prefix << FunctionName | 7290 Str << "\t.section\t" << Prefix << FunctionName |
| 7280 << "$jumptable,\"a\",@progbits\n"; | 7291 << "$jumptable,\"a\",@progbits\n"; |
| 7281 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 7292 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
| 7282 Str << InstJumpTable::makeName(FunctionName, JumpTable->getId()) << ":"; | 7293 Str << InstJumpTable::makeName(FunctionName, JumpTable->getId()) << ":"; |
| 7283 | 7294 |
| 7284 // On X86 ILP32 pointers are 32-bit hence the use of .long | 7295 // On X86 ILP32 pointers are 32-bit hence the use of .long |
| 7285 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) | 7296 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) |
| 7286 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); | 7297 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); |
| 7287 Str << "\n"; | 7298 Str << "\n"; |
| 7288 } | 7299 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7321 // Use memcpy() to copy bits from Value into RawValue in a way that avoids | 7332 // Use memcpy() to copy bits from Value into RawValue in a way that avoids |
| 7322 // breaking strict-aliasing rules. | 7333 // breaking strict-aliasing rules. |
| 7323 typename T::PrimitiveIntType RawValue; | 7334 typename T::PrimitiveIntType RawValue; |
| 7324 memcpy(&RawValue, &Value, sizeof(Value)); | 7335 memcpy(&RawValue, &Value, sizeof(Value)); |
| 7325 char buf[30]; | 7336 char buf[30]; |
| 7326 int CharsPrinted = | 7337 int CharsPrinted = |
| 7327 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 7338 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
| 7328 assert(CharsPrinted >= 0); | 7339 assert(CharsPrinted >= 0); |
| 7329 assert((size_t)CharsPrinted < llvm::array_lengthof(buf)); | 7340 assert((size_t)CharsPrinted < llvm::array_lengthof(buf)); |
| 7330 (void)CharsPrinted; // avoid warnings if asserts are disabled | 7341 (void)CharsPrinted; // avoid warnings if asserts are disabled |
| 7331 Const->emitPoolLabel(Str); | 7342 Str << Const->getLabelName(); |
| 7332 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " " | 7343 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " " |
| 7333 << Value << " */\n"; | 7344 << Value << " */\n"; |
| 7334 } | 7345 } |
| 7335 } | 7346 } |
| 7336 | 7347 |
| 7337 template <typename TraitsType> | 7348 template <typename TraitsType> |
| 7338 void TargetDataX86<TraitsType>::lowerConstants() { | 7349 void TargetDataX86<TraitsType>::lowerConstants() { |
| 7339 if (Ctx->getFlags().getDisableTranslation()) | 7350 if (Ctx->getFlags().getDisableTranslation()) |
| 7340 return; | 7351 return; |
| 7341 switch (Ctx->getFlags().getOutFileType()) { | 7352 switch (Ctx->getFlags().getOutFileType()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 7372 for (const JumpTableData &JT : Ctx->getJumpTables()) | 7383 for (const JumpTableData &JT : Ctx->getJumpTables()) |
| 7373 Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC); | 7384 Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC); |
| 7374 } break; | 7385 } break; |
| 7375 case FT_Asm: | 7386 case FT_Asm: |
| 7376 // Already emitted from Cfg | 7387 // Already emitted from Cfg |
| 7377 break; | 7388 break; |
| 7378 case FT_Iasm: { | 7389 case FT_Iasm: { |
| 7379 if (!BuildDefs::dump()) | 7390 if (!BuildDefs::dump()) |
| 7380 return; | 7391 return; |
| 7381 Ostream &Str = Ctx->getStrEmit(); | 7392 Ostream &Str = Ctx->getStrEmit(); |
| 7382 const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; | 7393 const char *Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; |
| 7383 for (const JumpTableData &JT : Ctx->getJumpTables()) { | 7394 for (const JumpTableData &JT : Ctx->getJumpTables()) { |
| 7384 Str << "\t.section\t" << Prefix << JT.getFunctionName() | 7395 Str << "\t.section\t" << Prefix << JT.getFunctionName() |
| 7385 << "$jumptable,\"a\",@progbits\n"; | 7396 << "$jumptable,\"a\",@progbits\n"; |
| 7386 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | 7397 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
| 7387 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; | 7398 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; |
| 7388 | 7399 |
| 7389 // On X8664 ILP32 pointers are 32-bit hence the use of .long | 7400 // On X8664 ILP32 pointers are 32-bit hence the use of .long |
| 7390 for (intptr_t TargetOffset : JT.getTargetOffsets()) | 7401 for (intptr_t TargetOffset : JT.getTargetOffsets()) |
| 7391 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; | 7402 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; |
| 7392 Str << "\n"; | 7403 Str << "\n"; |
| 7393 } | 7404 } |
| 7394 } break; | 7405 } break; |
| 7395 } | 7406 } |
| 7396 } | 7407 } |
| 7397 | 7408 |
| 7398 template <typename TraitsType> | 7409 template <typename TraitsType> |
| 7399 void TargetDataX86<TraitsType>::lowerGlobals( | 7410 void TargetDataX86<TraitsType>::lowerGlobals( |
| 7400 const VariableDeclarationList &Vars, const IceString &SectionSuffix) { | 7411 const VariableDeclarationList &Vars, const std::string &SectionSuffix) { |
| 7401 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | 7412 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); |
| 7402 switch (Ctx->getFlags().getOutFileType()) { | 7413 switch (Ctx->getFlags().getOutFileType()) { |
| 7403 case FT_Elf: { | 7414 case FT_Elf: { |
| 7404 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 7415 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
| 7405 Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC); | 7416 Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC); |
| 7406 } break; | 7417 } break; |
| 7407 case FT_Asm: | 7418 case FT_Asm: |
| 7408 case FT_Iasm: { | 7419 case FT_Iasm: { |
| 7409 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); | 7420 const std::string TranslateOnly = Ctx->getFlags().getTranslateOnly(); |
| 7410 OstreamLocker L(Ctx); | 7421 OstreamLocker L(Ctx); |
| 7411 for (const VariableDeclaration *Var : Vars) { | 7422 for (const VariableDeclaration *Var : Vars) { |
| 7412 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 7423 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
| 7413 emitGlobal(*Var, SectionSuffix); | 7424 emitGlobal(*Var, SectionSuffix); |
| 7414 } | 7425 } |
| 7415 } | 7426 } |
| 7416 } break; | 7427 } break; |
| 7417 } | 7428 } |
| 7418 } | 7429 } |
| 7419 } // end of namespace X86NAMESPACE | 7430 } // end of namespace X86NAMESPACE |
| 7420 } // end of namespace Ice | 7431 } // end of namespace Ice |
| 7421 | 7432 |
| 7422 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7433 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |