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

Unified Diff: src/IceInstARM32.cpp

Issue 1669973002: Fix ARM assembler to pop registers in reverse order of pushes. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Answer issues in CL. Created 4 years, 10 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/IceInstARM32.cpp
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index 9265515512ae3ac86954335bb09f4bd2cd896286..3ed8053f8ffffa5d6e042bdd1b47c4b8c0019586 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -898,13 +898,23 @@ void InstARM32RegisterStackOp::emitSRegsAsText(const Cfg *Func,
Str << "}";
}
+void InstARM32RegisterStackOp::emitSRegsOp(const Cfg *Func, EmitForm Form,
+ const Variable *BaseReg,
+ SizeT RegCount,
+ SizeT InstIndex) const {
+ if (Form == Emit_Text && BuildDefs::dump() && InstIndex > 0) {
+ startNextInst(Func);
+ Func->getContext()->getStrEmit() << "\n";
+ }
+ emitSRegs(Func, Form, BaseReg, RegCount);
+}
+
namespace {
bool isAssignedConsecutiveRegisters(const Variable *Before,
const Variable *After) {
- assert(Before->hasReg());
- assert(After->hasReg());
- return Before->getRegNum() + 1 == After->getRegNum();
+ return RegARM32::getEncodedSReg(Before->getRegNum()) + 1 ==
+ RegARM32::getEncodedSReg(After->getRegNum());
}
} // end of anonymous namespace
@@ -916,7 +926,7 @@ void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func,
const auto *Reg = llvm::cast<Variable>(getStackReg(0));
if (isScalarIntegerType(Reg->getType())) {
- // Pop GPR registers.
+ // Push/pop GPR registers.
SizeT IntegerCount = 0;
ARM32::IValueT GPRegisters = 0;
const Variable *LastDest = nullptr;
@@ -933,33 +943,43 @@ void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func,
} else {
emitMultipleGPRs(Func, Form, GPRegisters);
}
- } else {
- // Pop vector/floating point registers.
- const Variable *BaseReg = nullptr;
- SizeT RegCount = 0;
- for (SizeT i = 0; i < NumRegs; ++i) {
- const Variable *NextReg = getStackReg(i);
- if (BaseReg == nullptr) {
- BaseReg = NextReg;
- RegCount = 1;
- } else if (RegCount < VpushVpopMaxConsecRegs &&
- isAssignedConsecutiveRegisters(Reg, NextReg)) {
- ++RegCount;
- } else {
- emitSRegs(Func, Form, BaseReg, RegCount);
- if (Form == Emit_Text && BuildDefs::dump()) {
- startNextInst(Func);
- Func->getContext()->getStrEmit() << "\n";
- }
- BaseReg = NextReg;
- RegCount = 1;
- }
- Reg = NextReg;
- }
- if (RegCount) {
- emitSRegs(Func, Form, BaseReg, RegCount);
+ return;
+ }
+
+ // Push/pop floating point registers. Divide into a list of instructions,
+ // defined on consecutive register ranges. Then generate the corresponding
+ // instructions.
+ llvm::SmallVector<std::pair<const Variable *, SizeT>, 5> InstData;
Jim Stichnoth 2016/02/08 17:15:58 Could you document the choice of "5"? With a cons
Karl 2016/02/09 20:24:27 Done.
+ const Variable *BaseReg = nullptr;
+ SizeT RegCount = 0;
+ for (SizeT i = 0; i < NumRegs; ++i) {
+ const Variable *NextReg = getStackReg(i);
+ assert(NextReg->hasReg());
+ if (BaseReg == nullptr) {
+ BaseReg = NextReg;
+ RegCount = 1;
+ } else if (RegCount < VpushVpopMaxConsecRegs &&
+ isAssignedConsecutiveRegisters(Reg, NextReg)) {
+ ++RegCount;
+ } else {
+ InstData.push_back(std::make_pair(BaseReg, RegCount));
Jim Stichnoth 2016/02/08 17:15:58 InstData.emplace_back(BaseReg, RegCount);
Karl 2016/02/09 20:24:27 Done.
+ BaseReg = NextReg;
+ RegCount = 1;
}
+ Reg = NextReg;
+ }
+ if (RegCount) {
+ InstData.push_back(std::make_pair(BaseReg, RegCount));
Jim Stichnoth 2016/02/08 17:15:58 emplace_back
Karl 2016/02/09 20:24:27 Done.
+ }
+ SizeT InstCount = 0;
+ if (llvm::isa<InstARM32Push>(*this)) {
+ for (const auto &Pair : InstData)
+ emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++);
+ return;
}
+ assert(llvm::isa<InstARM32Pop>(*this));
+ for (const auto &Pair : reverse_range(InstData))
+ emitSRegsOp(Func, Form, Pair.first, Pair.second, InstCount++);
}
InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests)

Powered by Google App Engine
This is Rietveld 408576698