Index: src/IceTargetLoweringX8664.cpp |
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp |
index c023949476080c5e6c75bad4a001fd1fb4d4886e..ca92c171a8c34553e9653ff3d472902cf3fe4cd3 100644 |
--- a/src/IceTargetLoweringX8664.cpp |
+++ b/src/IceTargetLoweringX8664.cpp |
@@ -297,33 +297,48 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { |
// In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.) |
// NaCl sandboxing also requires that any registers that are not %rsp and |
// %rbp to be 'truncated' to 32-bit before memory access. |
- assert(NeedSandboxing); |
+ if (SandboxingType == ST_None) { |
+ return Mem; |
+ } |
+ |
+ if (SandboxingType == ST_Nonsfi) { |
+ llvm::report_fatal_error( |
+ "_sandbox_mem_reference not implemented for nonsfi"); |
+ } |
+ |
Variable *Base = Mem->getBase(); |
Variable *Index = Mem->getIndex(); |
uint16_t Shift = 0; |
- Variable *r15 = |
+ Variable *ZeroReg = |
getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
Constant *Offset = Mem->getOffset(); |
Variable *T = nullptr; |
if (Mem->getIsRebased()) { |
// If Mem.IsRebased, then we don't need to update Mem to contain a reference |
- // to %r15, but we still need to truncate Mem.Index (if any) to 32-bit. |
- assert(r15 == Base); |
- T = Index; |
- Shift = Mem->getShift(); |
- } else if (Base != nullptr && Index != nullptr) { |
- // Another approach could be to emit an |
- // |
- // lea Mem, %T |
- // |
- // And then update Mem.Base = r15, Mem.Index = T, Mem.Shift = 0 |
- llvm::report_fatal_error("memory reference contains base and index."); |
- } else if (Base != nullptr) { |
- T = Base; |
- } else if (Index != nullptr) { |
- T = Index; |
+ // to a valid base register (%r15, %rsp, or %rbp), but we still need to |
+ // truncate Mem.Index (if any) to 32-bit. |
+ assert(ZeroReg == Base || Base->isRematerializable()); |
+ T = makeReg(IceType_i32); |
+ _mov(T, Index); |
Shift = Mem->getShift(); |
+ } else { |
+ if (Base != nullptr) { |
+ if (Base->isRematerializable()) { |
+ ZeroReg = Base; |
+ } else { |
+ T = Base; |
+ } |
+ } |
+ |
+ if (Index != nullptr) { |
+ assert(!Index->isRematerializable()); |
+ if (T != nullptr) { |
+ llvm::report_fatal_error("memory reference contains base and index."); |
+ } |
+ T = Index; |
+ Shift = Mem->getShift(); |
+ } |
} |
// NeedsLea is a flags indicating whether Mem needs to be materialized to a |
@@ -398,7 +413,7 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { |
static constexpr bool IsRebased = true; |
return Traits::X86OperandMem::create( |
- Func, Mem->getType(), r15, Offset, T, Shift, |
+ Func, Mem->getType(), ZeroReg, Offset, T, Shift, |
Traits::X86OperandMem::DefaultSegment, IsRebased); |
} |
@@ -426,8 +441,23 @@ void TargetX8664::_sub_sp(Operand *Adjustment) { |
_add(rsp, r15); |
} |
+void TargetX8664::initRebasePtr() { |
+ switch (SandboxingType) { |
+ case ST_Nonsfi: |
+ // Probably no implementation is needed, but error to be safe for now. |
+ llvm::report_fatal_error( |
+ "initRebasePtr() is not yet implemented on x32-nonsfi."); |
+ case ST_NaCl: |
+ RebasePtr = getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
+ break; |
+ case ST_None: |
+ // nothing. |
+ break; |
+ } |
+} |
+ |
void TargetX8664::initSandbox() { |
- assert(NeedSandboxing); |
+ assert(SandboxingType == ST_NaCl); |
Context.init(Func->getEntryNode()); |
Context.setInsertPoint(Context.getCur()); |
Variable *r15 = |
@@ -436,6 +466,45 @@ void TargetX8664::initSandbox() { |
Context.insert<InstFakeUse>(r15); |
} |
+namespace { |
+bool isRematerializable(const Variable *Var) { |
+ return Var != nullptr && Var->isRematerializable(); |
+} |
+} // end of anonymous namespace |
+ |
+bool TargetX8664::legalizeOptAddrForSandbox(OptAddr *Addr) { |
+ if (SandboxingType == ST_Nonsfi) { |
+ llvm::report_fatal_error("Nonsfi not yet implemented for x8664."); |
+ } |
+ |
+ if (isRematerializable(Addr->Base)) { |
+ if (Addr->Index == RebasePtr) { |
+ Addr->Index = nullptr; |
+ Addr->Shift = 0; |
+ } |
+ return true; |
+ } |
+ |
+ if (isRematerializable(Addr->Index)) { |
+ if (Addr->Base == RebasePtr) { |
+ Addr->Base = nullptr; |
+ } |
+ return true; |
+ } |
+ |
+ assert(Addr->Base != RebasePtr && Addr->Index != RebasePtr); |
+ |
+ if (Addr->Base == nullptr) { |
+ return true; |
+ } |
+ |
+ if (Addr->Index == nullptr) { |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
void TargetX8664::lowerIndirectJump(Variable *JumpTarget) { |
std::unique_ptr<AutoBundle> Bundler; |