OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 }; | 70 }; |
71 | 71 |
72 void MachineTraits<TargetX8632>::X86Operand::dump(const Cfg *, | 72 void MachineTraits<TargetX8632>::X86Operand::dump(const Cfg *, |
73 Ostream &Str) const { | 73 Ostream &Str) const { |
74 if (BuildDefs::dump()) | 74 if (BuildDefs::dump()) |
75 Str << "<OperandX8632>"; | 75 Str << "<OperandX8632>"; |
76 } | 76 } |
77 | 77 |
78 MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem( | 78 MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem( |
79 Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index, | 79 Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index, |
80 uint16_t Shift, SegmentRegisters SegmentReg) | 80 uint16_t Shift, SegmentRegisters SegmentReg, bool IsPIC) |
81 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 81 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
82 Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { | 82 Shift(Shift), SegmentReg(SegmentReg), IsPIC(IsPIC) { |
83 assert(Shift <= 3); | 83 assert(Shift <= 3); |
84 Vars = nullptr; | 84 Vars = nullptr; |
85 NumVars = 0; | 85 NumVars = 0; |
86 if (Base) | 86 if (Base) |
87 ++NumVars; | 87 ++NumVars; |
88 if (Index) | 88 if (Index) |
89 ++NumVars; | 89 ++NumVars; |
90 if (NumVars) { | 90 if (NumVars) { |
91 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 91 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
92 SizeT I = 0; | 92 SizeT I = 0; |
93 if (Base) | 93 if (Base) |
94 Vars[I++] = Base; | 94 Vars[I++] = Base; |
95 if (Index) | 95 if (Index) |
96 Vars[I++] = Index; | 96 Vars[I++] = Index; |
97 assert(I == NumVars); | 97 assert(I == NumVars); |
98 } | 98 } |
99 } | 99 } |
100 | 100 |
101 namespace { | 101 namespace { |
102 static int32_t GetRematerializableOffset(Variable *Var, | 102 |
103 const Ice::TargetX8632 *Target) { | 103 int32_t GetRematerializableOffset(Variable *Var, |
| 104 const Ice::TargetX8632 *Target) { |
104 int32_t Disp = Var->getStackOffset(); | 105 int32_t Disp = Var->getStackOffset(); |
105 SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); | 106 SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); |
106 if (RegNum == Target->getFrameReg()) { | 107 if (RegNum == Target->getFrameReg()) { |
107 Disp += Target->getFrameFixedAllocaOffset(); | 108 Disp += Target->getFrameFixedAllocaOffset(); |
108 } else if (RegNum != Target->getStackReg()) { | 109 } else if (RegNum != Target->getStackReg()) { |
109 llvm::report_fatal_error("Unexpected rematerializable register type"); | 110 llvm::report_fatal_error("Unexpected rematerializable register type"); |
110 } | 111 } |
111 return Disp; | 112 return Disp; |
112 } | 113 } |
| 114 |
| 115 void validateMemOperandPIC(const MachineTraits<TargetX8632>::X86OperandMem *Mem, |
| 116 bool UseNonsfi) { |
| 117 if (!BuildDefs::asserts()) |
| 118 return; |
| 119 const bool HasCR = |
| 120 Mem->getOffset() && llvm::isa<ConstantRelocatable>(Mem->getOffset()); |
| 121 (void)HasCR; |
| 122 const bool IsPIC = Mem->getIsPIC(); |
| 123 (void)IsPIC; |
| 124 if (UseNonsfi) |
| 125 assert(HasCR == IsPIC); |
| 126 else |
| 127 assert(!IsPIC); |
| 128 } |
| 129 |
113 } // end of anonymous namespace | 130 } // end of anonymous namespace |
114 | 131 |
115 void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { | 132 void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { |
116 if (!BuildDefs::dump()) | 133 if (!BuildDefs::dump()) |
117 return; | 134 return; |
| 135 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
| 136 validateMemOperandPIC(this, UseNonsfi); |
118 const auto *Target = static_cast<const Ice::TargetX8632 *>(Func->getTarget()); | 137 const auto *Target = static_cast<const Ice::TargetX8632 *>(Func->getTarget()); |
119 // If the base is rematerializable, we need to replace it with the correct | 138 // If the base is rematerializable, we need to replace it with the correct |
120 // physical register (esp or ebp), and update the Offset. | 139 // physical register (esp or ebp), and update the Offset. |
121 int32_t Disp = 0; | 140 int32_t Disp = 0; |
122 if (getBase() && getBase()->isRematerializable()) { | 141 if (getBase() && getBase()->isRematerializable()) { |
123 Disp += GetRematerializableOffset(getBase(), Target); | 142 Disp += GetRematerializableOffset(getBase(), Target); |
124 } | 143 } |
125 // The index should never be rematerializable. But if we ever allow it, then | 144 // The index should never be rematerializable. But if we ever allow it, then |
126 // we should make sure the rematerialization offset is shifted by the Shift | 145 // we should make sure the rematerialization offset is shifted by the Shift |
127 // value. | 146 // value. |
128 if (getIndex()) | 147 if (getIndex()) |
129 assert(!getIndex()->isRematerializable()); | 148 assert(!getIndex()->isRematerializable()); |
130 Ostream &Str = Func->getContext()->getStrEmit(); | 149 Ostream &Str = Func->getContext()->getStrEmit(); |
131 if (SegmentReg != DefaultSegment) { | 150 if (SegmentReg != DefaultSegment) { |
132 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 151 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
133 Str << "%" << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":"; | 152 Str << "%" << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":"; |
134 } | 153 } |
135 // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading | 154 // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading |
136 // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. | 155 // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
137 if (getOffset() == 0 && Disp == 0) { | 156 if (getOffset() == nullptr && Disp == 0) { |
138 // No offset, emit nothing. | 157 // No offset, emit nothing. |
139 } else if (getOffset() == 0 && Disp != 0) { | 158 } else if (getOffset() == nullptr && Disp != 0) { |
140 Str << Disp; | 159 Str << Disp; |
141 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 160 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
142 if (getBase() == nullptr || CI->getValue() || Disp != 0) | 161 if (getBase() == nullptr || CI->getValue() || Disp != 0) |
143 // Emit a non-zero offset without a leading '$'. | 162 // Emit a non-zero offset without a leading '$'. |
144 Str << CI->getValue() + Disp; | 163 Str << CI->getValue() + Disp; |
145 } else if (const auto *CR = | 164 } else if (const auto *CR = |
146 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 165 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
147 // TODO(sehr): ConstantRelocatable still needs updating for | 166 // TODO(sehr): ConstantRelocatable still needs updating for |
148 // rematerializable base/index and Disp. | 167 // rematerializable base/index and Disp. |
149 assert(Disp == 0); | 168 assert(Disp == 0); |
150 CR->emitWithoutPrefix(Target); | 169 CR->emitWithoutPrefix(Target, UseNonsfi ? "@GOTOFF" : ""); |
151 } else { | 170 } else { |
152 llvm_unreachable("Invalid offset type for x86 mem operand"); | 171 llvm_unreachable("Invalid offset type for x86 mem operand"); |
153 } | 172 } |
154 | 173 |
155 if (getBase() || getIndex()) { | 174 if (getBase() || getIndex()) { |
156 Str << "("; | 175 Str << "("; |
157 if (getBase()) | 176 if (getBase()) |
158 getBase()->emit(Func); | 177 getBase()->emit(Func); |
159 if (getIndex()) { | 178 if (getIndex()) { |
160 Str << ","; | 179 Str << ","; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 if (SegmentReg != DefaultSegment) { | 254 if (SegmentReg != DefaultSegment) { |
236 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 255 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
237 Asm->emitSegmentOverride(X8632::Traits::InstSegmentPrefixes[SegmentReg]); | 256 Asm->emitSegmentOverride(X8632::Traits::InstSegmentPrefixes[SegmentReg]); |
238 } | 257 } |
239 } | 258 } |
240 | 259 |
241 MachineTraits<TargetX8632>::Address | 260 MachineTraits<TargetX8632>::Address |
242 MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress( | 261 MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress( |
243 MachineTraits<TargetX8632>::Assembler *Asm, | 262 MachineTraits<TargetX8632>::Assembler *Asm, |
244 const Ice::TargetLowering *TargetLowering) const { | 263 const Ice::TargetLowering *TargetLowering) const { |
| 264 const auto *Target = static_cast<const Ice::TargetX8632 *>(TargetLowering); |
| 265 const bool UseNonsfi = Target->getGlobalContext()->getFlags().getUseNonsfi(); |
| 266 validateMemOperandPIC(this, UseNonsfi); |
245 int32_t Disp = 0; | 267 int32_t Disp = 0; |
246 const auto *Target = static_cast<const Ice::TargetX8632 *>(TargetLowering); | |
247 if (getBase() && getBase()->isRematerializable()) { | 268 if (getBase() && getBase()->isRematerializable()) { |
248 Disp += GetRematerializableOffset(getBase(), Target); | 269 Disp += GetRematerializableOffset(getBase(), Target); |
249 } | 270 } |
250 // The index should never be rematerializable. But if we ever allow it, then | 271 // The index should never be rematerializable. But if we ever allow it, then |
251 // we should make sure the rematerialization offset is shifted by the Shift | 272 // we should make sure the rematerialization offset is shifted by the Shift |
252 // value. | 273 // value. |
253 if (getIndex()) | 274 if (getIndex()) |
254 assert(!getIndex()->isRematerializable()); | 275 assert(!getIndex()->isRematerializable()); |
255 AssemblerFixup *Fixup = nullptr; | 276 AssemblerFixup *Fixup = nullptr; |
256 // Determine the offset (is it relocatable?) | 277 // Determine the offset (is it relocatable?) |
257 if (getOffset()) { | 278 if (getOffset()) { |
258 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 279 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
259 Disp += static_cast<int32_t>(CI->getValue()); | 280 Disp += static_cast<int32_t>(CI->getValue()); |
260 } else if (const auto CR = | 281 } else if (const auto CR = |
261 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 282 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
262 Disp += CR->getOffset(); | 283 Disp += CR->getOffset(); |
263 Fixup = Asm->createFixup(RelFixup, CR); | 284 Fixup = Asm->createFixup(Target->getRelFixup(), CR); |
264 } else { | 285 } else { |
265 llvm_unreachable("Unexpected offset type"); | 286 llvm_unreachable("Unexpected offset type"); |
266 } | 287 } |
267 } | 288 } |
268 | 289 |
269 // Now convert to the various possible forms. | 290 // Now convert to the various possible forms. |
270 if (getBase() && getIndex()) { | 291 if (getBase() && getIndex()) { |
271 return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()), | 292 return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()), |
272 getEncodedGPR(getIndex()->getRegNum()), | 293 getEncodedGPR(getIndex()->getRegNum()), |
273 X8632::Traits::ScaleFactor(getShift()), Disp, | 294 X8632::Traits::ScaleFactor(getShift()), Disp, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 Var->dump(Func); | 345 Var->dump(Func); |
325 else | 346 else |
326 Var->dump(Str); | 347 Var->dump(Str); |
327 Str << ")"; | 348 Str << ")"; |
328 } | 349 } |
329 | 350 |
330 } // namespace X86Internal | 351 } // namespace X86Internal |
331 } // end of namespace Ice | 352 } // end of namespace Ice |
332 | 353 |
333 X86INSTS_DEFINE_STATIC_DATA(TargetX8632) | 354 X86INSTS_DEFINE_STATIC_DATA(TargetX8632) |
OLD | NEW |