Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.) | 212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.) |
| 213 AutoBundle _(this); | 213 AutoBundle _(this); |
| 214 _push(_0); | 214 _push(_0); |
| 215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack); | 215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack); |
| 216 } | 216 } |
| 217 | 217 |
| 218 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { | 218 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { |
| 219 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.) | 219 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.) |
| 220 // NaCl sandboxing also requires that any registers that are not %rsp and | 220 // NaCl sandboxing also requires that any registers that are not %rsp and |
| 221 // %rbp to be 'truncated' to 32-bit before memory access. | 221 // %rbp to be 'truncated' to 32-bit before memory access. |
| 222 assert(NeedSandboxing); | 222 if (SandboxingType == ST_None) { |
| 223 return Mem; | |
| 224 } | |
| 225 | |
| 226 if (SandboxingType == ST_Nonsfi) { | |
| 227 llvm::report_fatal_error( | |
| 228 "_sandbox_mem_reference not implemented for nonsfi"); | |
| 229 } | |
| 230 | |
| 223 Variable *Base = Mem->getBase(); | 231 Variable *Base = Mem->getBase(); |
| 224 Variable *Index = Mem->getIndex(); | 232 Variable *Index = Mem->getIndex(); |
| 225 uint16_t Shift = 0; | 233 uint16_t Shift = 0; |
| 226 Variable *r15 = | 234 Variable *ZeroReg = |
| 227 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); | 235 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
| 228 Constant *Offset = Mem->getOffset(); | 236 Constant *Offset = Mem->getOffset(); |
| 229 Variable *T = nullptr; | 237 Variable *T = nullptr; |
| 230 | 238 |
| 231 if (Mem->getIsRebased()) { | 239 if (Mem->getIsRebased()) { |
| 232 // If Mem.IsRebased, then we don't need to update Mem to contain a reference | 240 // If Mem.IsRebased, then we don't need to update Mem to contain a reference |
| 233 // to %r15, but we still need to truncate Mem.Index (if any) to 32-bit. | 241 // to a valid base register (%r15, %rsp, or %rbp), but we still need to |
| 234 assert(r15 == Base); | 242 // truncate Mem.Index (if any) to 32-bit. |
| 235 T = Index; | 243 assert(ZeroReg == Base || Base->isRematerializable()); |
| 244 T = makeReg(IceType_i32); | |
| 245 _mov(T, Index); | |
| 236 Shift = Mem->getShift(); | 246 Shift = Mem->getShift(); |
|
Jim Stichnoth
2016/01/22 02:44:10
Add an early return here, and pull the rest out of
John
2016/01/22 02:56:21
It's not possible. There's more code after the els
Jim Stichnoth
2016/01/22 03:08:55
Let me clarify (hopefully I'm not being stupid her
John
2016/01/22 04:18:07
That would not work:
void TargetX8664::_sandbox_m
Jim Stichnoth
2016/01/22 04:29:40
OK, it turns out I was indeed stupid. I misread t
| |
| 237 } else if (Base != nullptr && Index != nullptr) { | 247 } else { |
| 238 // Another approach could be to emit an | 248 if (Base != nullptr) { |
| 239 // | 249 if (Base->isRematerializable()) { |
| 240 // lea Mem, %T | 250 ZeroReg = Base; |
| 241 // | 251 } else { |
| 242 // And then update Mem.Base = r15, Mem.Index = T, Mem.Shift = 0 | 252 T = Base; |
| 243 llvm::report_fatal_error("memory reference contains base and index."); | 253 } |
| 244 } else if (Base != nullptr) { | 254 } |
| 245 T = Base; | 255 |
| 246 } else if (Index != nullptr) { | 256 if (Index != nullptr) { |
| 247 T = Index; | 257 assert(!Index->isRematerializable()); |
| 248 Shift = Mem->getShift(); | 258 if (T != nullptr) { |
| 259 llvm::report_fatal_error("memory reference contains base and index."); | |
| 260 } | |
| 261 T = Index; | |
| 262 Shift = Mem->getShift(); | |
| 263 } | |
| 249 } | 264 } |
| 250 | 265 |
| 251 // NeedsLea is a flags indicating whether Mem needs to be materialized to a | 266 // NeedsLea is a flags indicating whether Mem needs to be materialized to a |
| 252 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant | 267 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant |
| 253 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is | 268 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is |
| 254 // needed to ensure the sandboxed memory operand will only use the lower | 269 // needed to ensure the sandboxed memory operand will only use the lower |
| 255 // 32-bits of T+Offset. | 270 // 32-bits of T+Offset. |
| 256 bool NeedsLea = false; | 271 bool NeedsLea = false; |
| 257 if (const auto *Offset = Mem->getOffset()) { | 272 if (const auto *Offset = Mem->getOffset()) { |
| 258 if (llvm::isa<ConstantRelocatable>(Offset)) { | 273 if (llvm::isa<ConstantRelocatable>(Offset)) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 Traits::X86OperandMem::DefaultSegment, NotRebased)); | 328 Traits::X86OperandMem::DefaultSegment, NotRebased)); |
| 314 | 329 |
| 315 T = makeReg(IceType_i64, RegNum); | 330 T = makeReg(IceType_i64, RegNum); |
| 316 _movzx(T, NewT); | 331 _movzx(T, NewT); |
| 317 Shift = 0; | 332 Shift = 0; |
| 318 Offset = nullptr; | 333 Offset = nullptr; |
| 319 } | 334 } |
| 320 | 335 |
| 321 static constexpr bool IsRebased = true; | 336 static constexpr bool IsRebased = true; |
| 322 return Traits::X86OperandMem::create( | 337 return Traits::X86OperandMem::create( |
| 323 Func, Mem->getType(), r15, Offset, T, Shift, | 338 Func, Mem->getType(), ZeroReg, Offset, T, Shift, |
| 324 Traits::X86OperandMem::DefaultSegment, IsRebased); | 339 Traits::X86OperandMem::DefaultSegment, IsRebased); |
| 325 } | 340 } |
| 326 | 341 |
| 327 void TargetX8664::_sub_sp(Operand *Adjustment) { | 342 void TargetX8664::_sub_sp(Operand *Adjustment) { |
| 328 Variable *rsp = | 343 Variable *rsp = |
| 329 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); | 344 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); |
| 330 if (!NeedSandboxing) { | 345 if (!NeedSandboxing) { |
| 331 _sub(rsp, Adjustment); | 346 _sub(rsp, Adjustment); |
| 332 return; | 347 return; |
| 333 } | 348 } |
| 334 | 349 |
| 335 Variable *esp = | 350 Variable *esp = |
| 336 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32); | 351 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32); |
| 337 Variable *r15 = | 352 Variable *r15 = |
| 338 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); | 353 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
| 339 | 354 |
| 340 // .bundle_start | 355 // .bundle_start |
| 341 // sub Adjustment, %esp | 356 // sub Adjustment, %esp |
| 342 // add %r15, %rsp | 357 // add %r15, %rsp |
| 343 // .bundle_end | 358 // .bundle_end |
| 344 AutoBundle _(this); | 359 AutoBundle _(this); |
| 345 _redefined(Context.insert<InstFakeDef>(esp, rsp)); | 360 _redefined(Context.insert<InstFakeDef>(esp, rsp)); |
| 346 _sub(esp, Adjustment); | 361 _sub(esp, Adjustment); |
| 347 _redefined(Context.insert<InstFakeDef>(rsp, esp)); | 362 _redefined(Context.insert<InstFakeDef>(rsp, esp)); |
| 348 _add(rsp, r15); | 363 _add(rsp, r15); |
| 349 } | 364 } |
| 350 | 365 |
| 366 void TargetX8664::initSandboxPtr() { | |
| 367 switch (SandboxingType) { | |
| 368 case ST_Nonsfi: | |
| 369 // Probably no implementation is needed, but error to be safe for now. | |
| 370 llvm::report_fatal_error("Need to implement initSandboxPtr() for 64-bit."); | |
|
Jim Stichnoth
2016/01/22 02:44:10
I would add "nonsfi" to this error string.
John
2016/01/22 04:18:07
Done.
| |
| 371 case ST_NaCl: | |
| 372 SandboxPtr = getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); | |
| 373 break; | |
| 374 case ST_None: | |
| 375 // nothing. | |
| 376 break; | |
| 377 } | |
| 378 } | |
| 379 | |
| 351 void TargetX8664::initSandbox() { | 380 void TargetX8664::initSandbox() { |
| 352 assert(NeedSandboxing); | 381 assert(NeedSandboxing); |
|
Jim Stichnoth
2016/01/22 02:44:10
This function should probably be checking Sandboxi
John
2016/01/22 04:18:07
It is: NeedSandboxing --> SandboxingType == ST_NaC
| |
| 353 Context.init(Func->getEntryNode()); | 382 Context.init(Func->getEntryNode()); |
| 354 Context.setInsertPoint(Context.getCur()); | 383 Context.setInsertPoint(Context.getCur()); |
| 355 Variable *r15 = | 384 Variable *r15 = |
| 356 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); | 385 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
| 357 Context.insert<InstFakeDef>(r15); | 386 Context.insert<InstFakeDef>(r15); |
| 358 Context.insert<InstFakeUse>(r15); | 387 Context.insert<InstFakeUse>(r15); |
| 359 } | 388 } |
| 360 | 389 |
| 390 namespace { | |
| 391 bool isRematerializable(const Variable *Var) { | |
| 392 return Var != nullptr && Var->isRematerializable(); | |
| 393 } | |
| 394 } // end of anonymous namespace | |
| 395 | |
| 396 bool TargetX8664::legalizeOptAddrForSandbox(OptAddr *Addr) { | |
| 397 if (SandboxingType == ST_Nonsfi) { | |
| 398 llvm::report_fatal_error("Nonsfi not yet implemented for x8664."); | |
| 399 } | |
| 400 | |
| 401 if (isRematerializable(Addr->Base)) { | |
| 402 if (Addr->Index == SandboxPtr) { | |
| 403 Addr->Index = nullptr; | |
| 404 Addr->Shift = 0; | |
| 405 } | |
| 406 return true; | |
| 407 } | |
| 408 | |
| 409 if (isRematerializable(Addr->Index)) { | |
| 410 if (Addr->Base == SandboxPtr) { | |
| 411 Addr->Base = nullptr; | |
| 412 } | |
| 413 return true; | |
| 414 } | |
| 415 | |
| 416 assert(Addr->Base != SandboxPtr && Addr->Index != SandboxPtr); | |
| 417 | |
| 418 if (Addr->Base == nullptr) { | |
| 419 // Addr->Base = SandboxPtr; | |
|
Jim Stichnoth
2016/01/22 02:44:10
Remove the commented code, here and below?
John
2016/01/22 04:18:07
Done.
| |
| 420 return true; | |
| 421 } | |
| 422 | |
| 423 if (Addr->Index == nullptr) { | |
| 424 // Addr->Index = SandboxPtr; | |
| 425 // Addr->Shift = 0; | |
| 426 return true; | |
| 427 } | |
| 428 | |
| 429 return false; | |
| 430 } | |
| 431 | |
| 361 void TargetX8664::lowerIndirectJump(Variable *JumpTarget) { | 432 void TargetX8664::lowerIndirectJump(Variable *JumpTarget) { |
| 362 std::unique_ptr<AutoBundle> Bundler; | 433 std::unique_ptr<AutoBundle> Bundler; |
| 363 | 434 |
| 364 if (!NeedSandboxing) { | 435 if (!NeedSandboxing) { |
| 365 Variable *T = makeReg(IceType_i64); | 436 Variable *T = makeReg(IceType_i64); |
| 366 _movzx(T, JumpTarget); | 437 _movzx(T, JumpTarget); |
| 367 JumpTarget = T; | 438 JumpTarget = T; |
| 368 } else { | 439 } else { |
| 369 Variable *T = makeReg(IceType_i32); | 440 Variable *T = makeReg(IceType_i32); |
| 370 Variable *T64 = makeReg(IceType_i64); | 441 Variable *T64 = makeReg(IceType_i64); |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1146 #define X(tag, sizeLog2, align, elts, elty, str) \ | 1217 #define X(tag, sizeLog2, align, elts, elty, str) \ |
| 1147 static_assert(_table1_##tag == _table2_##tag, \ | 1218 static_assert(_table1_##tag == _table2_##tag, \ |
| 1148 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); | 1219 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); |
| 1149 ICETYPE_TABLE | 1220 ICETYPE_TABLE |
| 1150 #undef X | 1221 #undef X |
| 1151 } // end of namespace dummy3 | 1222 } // end of namespace dummy3 |
| 1152 } // end of anonymous namespace | 1223 } // end of anonymous namespace |
| 1153 | 1224 |
| 1154 } // end of namespace X8664 | 1225 } // end of namespace X8664 |
| 1155 } // end of namespace Ice | 1226 } // end of namespace Ice |
| OLD | NEW |