OLD | NEW |
1 //===- subzero/src/IceInstX8664.cpp - X86-64 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8664.cpp - X86-64 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 | 60 |
61 void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const { | 61 void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const { |
62 if (BuildDefs::dump()) | 62 if (BuildDefs::dump()) |
63 Str << "<OperandX8664>"; | 63 Str << "<OperandX8664>"; |
64 } | 64 } |
65 | 65 |
66 TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, | 66 TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, |
67 Variable *Base, | 67 Variable *Base, |
68 Constant *Offset, | 68 Constant *Offset, |
69 Variable *Index, uint16_t Shift, | 69 Variable *Index, uint16_t Shift, |
70 bool IsPIC) | 70 bool IsRebased) |
71 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 71 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
72 Shift(Shift), IsPIC(IsPIC) { | 72 Shift(Shift), IsRebased(IsRebased) { |
73 assert(Shift <= 3); | 73 assert(Shift <= 3); |
74 Vars = nullptr; | 74 Vars = nullptr; |
75 NumVars = 0; | 75 NumVars = 0; |
76 if (Base) | 76 if (Base) |
77 ++NumVars; | 77 ++NumVars; |
78 if (Index) | 78 if (Index) |
79 ++NumVars; | 79 ++NumVars; |
80 if (NumVars) { | 80 if (NumVars) { |
81 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 81 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
82 SizeT I = 0; | 82 SizeT I = 0; |
(...skipping 20 matching lines...) Expand all Loading... |
103 } | 103 } |
104 } // end of anonymous namespace | 104 } // end of anonymous namespace |
105 | 105 |
106 void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { | 106 void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const { |
107 if (!BuildDefs::dump()) | 107 if (!BuildDefs::dump()) |
108 return; | 108 return; |
109 const auto *Target = | 109 const auto *Target = |
110 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); | 110 static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget()); |
111 // If the base is rematerializable, we need to replace it with the correct | 111 // If the base is rematerializable, we need to replace it with the correct |
112 // physical register (stack or base pointer), and update the Offset. | 112 // physical register (stack or base pointer), and update the Offset. |
| 113 const bool NeedSandboxing = Target->needSandboxing(); |
113 int32_t Disp = 0; | 114 int32_t Disp = 0; |
114 if (getBase() && getBase()->isRematerializable()) { | 115 if (getBase() && getBase()->isRematerializable()) { |
115 Disp += getRematerializableOffset(getBase(), Target); | 116 Disp += getRematerializableOffset(getBase(), Target); |
116 } | 117 } |
117 // The index should never be rematerializable. But if we ever allow it, then | 118 // The index should never be rematerializable. But if we ever allow it, then |
118 // we should make sure the rematerialization offset is shifted by the Shift | 119 // we should make sure the rematerialization offset is shifted by the Shift |
119 // value. | 120 // value. |
120 if (getIndex()) | 121 if (getIndex()) |
121 assert(!getIndex()->isRematerializable()); | 122 assert(!getIndex()->isRematerializable()); |
122 Ostream &Str = Func->getContext()->getStrEmit(); | 123 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 10 matching lines...) Expand all Loading... |
133 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 134 } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
134 // TODO(sehr): ConstantRelocatable still needs updating for | 135 // TODO(sehr): ConstantRelocatable still needs updating for |
135 // rematerializable base/index and Disp. | 136 // rematerializable base/index and Disp. |
136 assert(Disp == 0); | 137 assert(Disp == 0); |
137 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); | 138 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
138 CR->emitWithoutPrefix(Func->getTarget(), UseNonsfi ? "@GOTOFF" : ""); | 139 CR->emitWithoutPrefix(Func->getTarget(), UseNonsfi ? "@GOTOFF" : ""); |
139 } else { | 140 } else { |
140 llvm_unreachable("Invalid offset type for x86 mem operand"); | 141 llvm_unreachable("Invalid offset type for x86 mem operand"); |
141 } | 142 } |
142 | 143 |
143 if (Base || Index) { | 144 if (!Base && !Index) { |
144 Str << "("; | 145 return; |
145 if (Base) { | 146 } |
146 const Variable *Base32 = Base; | 147 |
| 148 Str << "("; |
| 149 if (Base != nullptr) { |
| 150 const Variable *B = Base; |
| 151 if (!NeedSandboxing) { |
147 if (Base->getType() != IceType_i32) { | 152 if (Base->getType() != IceType_i32) { |
148 // X86-64 is ILP32, but %rsp and %rbp are accessed as 64-bit registers. | 153 // X86-64 is ILP32, but %rsp and %rbp are accessed as 64-bit registers. |
149 // For filetype=asm, they need to be emitted as their 32-bit sibilings. | 154 // For filetype=asm, they need to be emitted as their 32-bit sibilings. |
150 assert(Base->getType() == IceType_i64); | 155 assert(Base->getType() == IceType_i64); |
151 assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || | 156 assert(Base->getRegNum() == RegX8664::Encoded_Reg_rsp || |
152 Base->getRegNum() == RegX8664::Encoded_Reg_rbp); | 157 Base->getRegNum() == RegX8664::Encoded_Reg_rbp); |
153 Base32 = Base->asType(IceType_i32, X8664::Traits::getGprForType( | 158 B = B->asType(IceType_i32, X8664::Traits::getGprForType( |
154 IceType_i32, Base->getRegNum())); | 159 IceType_i32, Base->getRegNum())); |
155 } | 160 } |
156 Base32->emit(Func); | |
157 } | 161 } |
158 if (Index) { | 162 |
159 assert(Index->getType() == IceType_i32); | 163 B->emit(Func); |
160 Str << ","; | |
161 Index->emit(Func); | |
162 if (Shift) | |
163 Str << "," << (1u << Shift); | |
164 } | |
165 Str << ")"; | |
166 } | 164 } |
| 165 |
| 166 if (Index != nullptr) { |
| 167 Variable *I = Index; |
| 168 Str << ","; |
| 169 I->emit(Func); |
| 170 if (Shift) |
| 171 Str << "," << (1u << Shift); |
| 172 } |
| 173 |
| 174 Str << ")"; |
167 } | 175 } |
168 | 176 |
169 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, | 177 void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func, |
170 Ostream &Str) const { | 178 Ostream &Str) const { |
171 if (!BuildDefs::dump()) | 179 if (!BuildDefs::dump()) |
172 return; | 180 return; |
173 bool Dumped = false; | 181 bool Dumped = false; |
174 Str << "["; | 182 Str << "["; |
175 int32_t Disp = 0; | 183 int32_t Disp = 0; |
176 const auto *Target = | 184 const auto *Target = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 } | 229 } |
222 } else { | 230 } else { |
223 // There is only the offset. | 231 // There is only the offset. |
224 Offset->dump(Func, Str); | 232 Offset->dump(Func, Str); |
225 } | 233 } |
226 Str << "]"; | 234 Str << "]"; |
227 } | 235 } |
228 | 236 |
229 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( | 237 TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress( |
230 TargetX8664Traits::Assembler *Asm, | 238 TargetX8664Traits::Assembler *Asm, |
231 const Ice::TargetLowering *TargetLowering) const { | 239 const Ice::TargetLowering *TargetLowering, bool LeaAddr) const { |
| 240 (void)LeaAddr; |
232 const auto *Target = | 241 const auto *Target = |
233 static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); | 242 static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering); |
| 243 const bool NeedSandboxing = Target->needSandboxing(); |
| 244 (void)NeedSandboxing; |
234 int32_t Disp = 0; | 245 int32_t Disp = 0; |
235 if (getBase() && getBase()->isRematerializable()) { | 246 if (getBase() && getBase()->isRematerializable()) { |
236 Disp += getRematerializableOffset(getBase(), Target); | 247 Disp += getRematerializableOffset(getBase(), Target); |
237 } | 248 } |
238 if (getIndex()) | 249 if (getIndex() != nullptr) { |
239 assert(!getIndex()->isRematerializable()); | 250 assert(!getIndex()->isRematerializable()); |
| 251 } |
| 252 |
240 AssemblerFixup *Fixup = nullptr; | 253 AssemblerFixup *Fixup = nullptr; |
241 // Determine the offset (is it relocatable?) | 254 // Determine the offset (is it relocatable?) |
242 if (getOffset() != nullptr) { | 255 if (getOffset() != nullptr) { |
243 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 256 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
244 Disp += static_cast<int32_t>(CI->getValue()); | 257 Disp += static_cast<int32_t>(CI->getValue()); |
245 } else if (const auto CR = | 258 } else if (const auto CR = |
246 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 259 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
247 Disp = CR->getOffset(); | 260 Disp = CR->getOffset(); |
248 Fixup = Asm->createFixup(FK_Abs, CR); | 261 Fixup = Asm->createFixup(FK_Abs, CR); |
249 } else { | 262 } else { |
250 llvm_unreachable("Unexpected offset type"); | 263 llvm_unreachable("Unexpected offset type"); |
251 } | 264 } |
252 } | 265 } |
253 | 266 |
254 // Now convert to the various possible forms. | 267 // Now convert to the various possible forms. |
255 if (getBase() && getIndex()) { | 268 if (getBase() && getIndex()) { |
| 269 assert(!NeedSandboxing || LeaAddr || |
| 270 (getBase()->getRegNum() == Traits::RegisterSet::Reg_r15)); |
256 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), | 271 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), |
257 getEncodedGPR(getIndex()->getRegNum()), | 272 getEncodedGPR(getIndex()->getRegNum()), |
258 X8664::Traits::ScaleFactor(getShift()), Disp, | 273 X8664::Traits::ScaleFactor(getShift()), Disp, |
259 Fixup); | 274 Fixup); |
260 } else if (getBase()) { | 275 } |
| 276 |
| 277 if (getBase()) { |
261 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, | 278 return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp, |
262 Fixup); | 279 Fixup); |
263 } else if (getIndex()) { | 280 } |
| 281 |
| 282 if (getIndex()) { |
264 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), | 283 return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()), |
265 X8664::Traits::ScaleFactor(getShift()), Disp, | 284 X8664::Traits::ScaleFactor(getShift()), Disp, |
266 Fixup); | 285 Fixup); |
267 } else { | |
268 return X8664::Traits::Address(Disp, Fixup); | |
269 } | 286 } |
| 287 |
| 288 return X8664::Traits::Address(Disp, Fixup); |
270 } | 289 } |
271 | 290 |
272 TargetX8664Traits::Address | 291 TargetX8664Traits::Address |
273 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { | 292 TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const { |
274 assert(!Var->hasReg()); | 293 assert(!Var->hasReg()); |
275 const ::Ice::TargetLowering *Target = Func->getTarget(); | 294 const ::Ice::TargetLowering *Target = Func->getTarget(); |
276 int32_t Offset = Var->getStackOffset() + getOffset(); | 295 int32_t Offset = Var->getStackOffset() + getOffset(); |
277 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), | 296 return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()), |
278 Offset, AssemblerFixup::NoFixup); | 297 Offset, AssemblerFixup::NoFixup); |
279 } | 298 } |
(...skipping 29 matching lines...) Expand all Loading... |
309 Var->dump(Func); | 328 Var->dump(Func); |
310 else | 329 else |
311 Var->dump(Str); | 330 Var->dump(Str); |
312 Str << ")"; | 331 Str << ")"; |
313 } | 332 } |
314 | 333 |
315 } // namespace X8664 | 334 } // namespace X8664 |
316 } // end of namespace Ice | 335 } // end of namespace Ice |
317 | 336 |
318 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) | 337 X86INSTS_DEFINE_STATIC_DATA(X8664, X8664::Traits) |
OLD | NEW |