Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(835)

Unified Diff: src/IceTargetLoweringX8664.cpp

Issue 1616103002: Subzero. X8664. Enables RIP-based addressing mode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make presubmit happy. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceTargetLoweringX8664.cpp
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index e46569bea008add9457f86771fb2048d54247a9a..73c2cb8a85f1f9e2c4c5c28d6fb01b5206c599ae 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -294,10 +294,31 @@ void TargetX8664::emitGetIP(CfgNode *Node) {
(void)Node;
}
+namespace {
+bool isAssignedToRspOrRbp(const Variable *Var) {
+ if (Var == nullptr) {
+ return false;
+ }
+
+ if (Var->isRematerializable()) {
+ return true;
+ }
+
+ if (!Var->hasReg()) {
Jim Stichnoth 2016/01/23 01:57:47 Optional: You could skip this condition if you wan
John 2016/01/26 19:44:25 I did not know that. I will leave this as is -- ex
+ return false;
+ }
+
+ int32_t RegNum = Var->getRegNum();
Jim Stichnoth 2016/01/23 01:57:47 const
John 2016/01/26 19:44:25 Done.
+ if ((RegNum == Traits::RegisterSet::Reg_rsp) ||
+ (RegNum == Traits::RegisterSet::Reg_rbp)) {
+ return true;
+ }
+
+ return false;
+}
+} // end of anonymous namespace
+
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.
if (SandboxingType == ST_None) {
return Mem;
}
@@ -307,25 +328,37 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
"_sandbox_mem_reference not implemented for nonsfi");
}
+ // In x86_64-nacl, all memory references are relative to a base register
+ // (%r15, %rsp, %rbp, or %rip).
+
Variable *Base = Mem->getBase();
Variable *Index = Mem->getIndex();
uint16_t Shift = 0;
- Variable *ZeroReg =
- getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
+ Variable *ZeroReg = RebasePtr;
Constant *Offset = Mem->getOffset();
Variable *T = nullptr;
+ if (Base == nullptr && Index == nullptr) {
+ // Mem is RIP-relative. There's no need to rebase it.
+ return Mem;
+ }
+
if (Mem->getIsRebased()) {
- // If Mem.IsRebased, then we don't need to update Mem to contain a reference
- // 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();
+ // If Mem.IsRebased, then we don't need to update Mem, as it's already been
+ // updated to contain a reference to one of %rsp, %rbp, or %r15.
+ // We don't return early because we still need to zero extend Index.
Jim Stichnoth 2016/01/23 01:57:47 Is the "don't return early" comment because of my
John 2016/01/26 19:44:25 no, it is not. The previous comment said "but we s
+ assert(ZeroReg == Base || isAssignedToRspOrRbp(Base));
+ ZeroReg = Base;
+ if (Index != nullptr) {
+ T = makeReg(IceType_i32);
+ _mov(T, Index);
+ Shift = Mem->getShift();
+ }
} else {
if (Base != nullptr) {
- if (Base->isRematerializable()) {
+ // If Base is a valid base pointer we don't need to use the RebasePtr. By
+ // doing this we might save us the need to zero extend the memory operand.
+ if (isAssignedToRspOrRbp(Base)) {
ZeroReg = Base;
} else {
T = Base;
@@ -334,11 +367,23 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
if (Index != nullptr) {
assert(!Index->isRematerializable());
+ // If Index is not nullptr, it is mandatory that T is a nullptr.
+ // Otherwise, the lowering generated an memory operand with two registers.
Jim Stichnoth 2016/01/23 01:57:47 s/an/a/
John 2016/01/26 19:44:25 Done.
+ // Note that Base might still be non-nullptr, but it must be a valid
+ // base register.
if (T != nullptr) {
llvm::report_fatal_error("memory reference contains base and index.");
}
- T = Index;
- Shift = Mem->getShift();
+ // If the Index is not shifted, and it is a Valid Base, and the ZeroReg is
+ // still RebasePtr, then we do ZeroReg = Index, and hopefully prevent the
+ // need to zero-extend the memory operand (which may still happen -- see
+ // NeedLea below.)
+ if (Shift == 0 && isAssignedToRspOrRbp(Index) && ZeroReg == RebasePtr) {
+ ZeroReg = Index;
+ } else {
+ T = Index;
+ Shift = Mem->getShift();
+ }
}
}
@@ -362,21 +407,20 @@ Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
if (T->hasReg()) {
RegNum = Traits::getGprForType(IceType_i64, T->getRegNum());
RegNum32 = Traits::getGprForType(IceType_i32, RegNum);
- switch (RegNum) {
- case Traits::RegisterSet::Reg_rsp:
- case Traits::RegisterSet::Reg_rbp:
- // Memory operands referencing rsp/rbp do not need to be sandboxed.
- return Mem;
- }
+ // At this point, if T was assigned to rsp/rbp, then we would have already
+ // made this the ZeroReg.
+ assert(RegNum != Traits::RegisterSet::Reg_rsp);
+ assert(RegNum != Traits::RegisterSet::Reg_rbp);
}
switch (T->getType()) {
default:
+ llvm::report_fatal_error("Mem pointer should be a 32-bit integer.");
Jim Stichnoth 2016/01/23 01:57:47 Here and below, would it make more sense to say "G
John 2016/01/26 19:44:25 I tend to think about GPRs/Regs in the assembler.
case IceType_i64:
// Even though "default:" would also catch T.Type == IceType_i64, an
// explicit 'case IceType_i64' shows that memory operands are always
// supposed to be 32-bits.
- llvm::report_fatal_error("Mem pointer should be 32-bit.");
+ llvm::report_fatal_error("Mem pointer should not be a 64-bit integer.");
case IceType_i32: {
Variable *T64 = makeReg(IceType_i64, RegNum);
auto *Movzx = _movzx(T64, T);

Powered by Google App Engine
This is Rietveld 408576698