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 GlobalString JTName( |
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 |