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

Unified Diff: src/IceInstARM32.cpp

Issue 1481133002: Subzero. ARM32. Show FP lowering some love. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years 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 6932d2f9d01ba502c906ec2e7425c2b60aaeda5a..252c4cc8a10e68a66e4254fae26d37731783fc78 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -185,6 +185,22 @@ void InstARM32::emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst,
Inst->getSrc(1)->emit(Func);
}
+void InstARM32::emitFourAddrFP(const char *Opcode, const InstARM32 *Inst,
+ const Cfg *Func) {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(Inst->getSrcSize() == 3);
+ assert(Inst->getSrc(0) == Inst->getDest());
+ Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType())
+ << "\t";
+ Inst->getDest()->emit(Func);
+ Str << ", ";
+ Inst->getSrc(1)->emit(Func);
+ Str << ", ";
+ Inst->getSrc(2)->emit(Func);
+}
+
void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst,
const Cfg *Func) {
if (!BuildDefs::dump())
@@ -563,12 +579,25 @@ InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests)
// instruction affects the stack pointer and so it should not be allowed to
// be automatically dead-code eliminated. This is automatic since we leave
// the Dest as nullptr.
+ Type PreviousTy = IceType_void;
Jim Stichnoth 2015/12/07 20:58:14 What do you think about adding this? if (BuildD
John 2015/12/08 13:54:24 This seems like a serious error that should be ver
Jim Stichnoth 2015/12/08 19:20:16 The only argument for removing it would be a very
+ for (Variable *Dest : Dests) {
+ if (PreviousTy != IceType_void && Dest->getType() != PreviousTy) {
+ llvm::report_fatal_error("Type mismatch when popping registers.");
+ }
+ PreviousTy = Dest->getType();
+ }
}
InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs)
: InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) {
- for (Variable *Source : Srcs)
+ Type PreviousTy = IceType_void;
+ for (Variable *Source : Srcs) {
+ if (PreviousTy != IceType_void && Source->getType() != PreviousTy) {
+ llvm::report_fatal_error("Type mismatch when pushing registers.");
+ }
addSource(Source);
+ PreviousTy = Source->getType();
+ }
}
InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
@@ -714,8 +743,10 @@ template <> const char *InstARM32Udiv::Opcode = "udiv";
// FP
template <> const char *InstARM32Vadd::Opcode = "vadd";
template <> const char *InstARM32Vdiv::Opcode = "vdiv";
-template <> const char *InstARM32Vmul::Opcode = "vmul";
template <> const char *InstARM32Veor::Opcode = "veor";
+template <> const char *InstARM32Vmla::Opcode = "vmla";
+template <> const char *InstARM32Vmls::Opcode = "vmls";
+template <> const char *InstARM32Vmul::Opcode = "vmul";
template <> const char *InstARM32Vsub::Opcode = "vsub";
// Four-addr ops
template <> const char *InstARM32Mla::Opcode = "mla";
@@ -1186,51 +1217,72 @@ template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
+namespace {
+
+bool AssignedConsecutiveRegisters(Operand *Before, Operand *After) {
Jim Stichnoth 2015/12/07 20:58:14 Maybe isAssignedConsecutiveRegisters() ? (in any
John 2015/12/08 13:54:24 Done. PS: don't be sorry for the code style. :)
+ return llvm::cast<Variable>(Before)->getRegNum() + 1 ==
Jim Stichnoth 2015/12/07 20:58:14 I think you should make Before and After both Vari
John 2015/12/08 13:54:24 I am asserting here because I moved the actual tes
+ llvm::cast<Variable>(After)->getRegNum();
+}
+
+} // end of anonymous namespace
+
void InstARM32Pop::emit(const Cfg *Func) const {
// TODO(jpp): Improve FP register save/restore.
if (!BuildDefs::dump())
return;
- SizeT IntegerCount = 0;
- for (const Operand *Op : Dests) {
- if (isScalarIntegerType(Op->getType())) {
- ++IntegerCount;
- }
- }
Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnoth 2015/12/07 20:58:14 Maybe move this after the DestSize assert / early
John 2015/12/08 13:54:24 Done.
- bool NeedNewline = false;
- if (IntegerCount != 0) {
+ const SizeT DestSize = Dests.size();
+ assert(DestSize > 0);
Jim Stichnoth 2015/12/07 20:58:14 Maybe move the assert into the "if" branch, right
John 2015/12/08 13:54:24 Done.
Jim Stichnoth 2015/12/08 19:20:16 Actually, looks like not (yet) done...
John 2015/12/09 13:11:08 Done.
+ if (DestSize == 0) {
+ return;
+ }
+
+ Operand *Op = Dests[0];
Jim Stichnoth 2015/12/07 20:58:14 Can this be declared as Variable* ? Maybe "Variab
John 2015/12/08 13:54:24 Done.
+ if (isScalarIntegerType(Op->getType())) {
+ // GPR push.
Str << "\t"
- << "pop"
- << "\t{";
- bool PrintComma = false;
- for (const Operand *Op : Dests) {
- if (isScalarIntegerType(Op->getType())) {
- if (PrintComma)
- Str << ", ";
- Op->emit(Func);
- PrintComma = true;
- }
+ "pop"
+ "\t{";
+ Op->emit(Func);
+ for (SizeT i = 1; i < DestSize; ++i) {
+ Str << ", ";
+ Op = Dests[i];
+ Op->emit(Func);
}
Str << "}";
- NeedNewline = true;
+ return;
Karl 2015/12/07 19:11:07 I assume you return here because you modified the
John 2015/12/08 13:54:24 That's correct.
}
- for (const Operand *Op : Dests) {
- if (isScalarIntegerType(Op->getType()))
- continue;
- if (NeedNewline) {
- Str << "\n";
+ // VFP "s" reg push.
+ SizeT End = DestSize - 1;
+ SizeT Start = DestSize - 1;
+ Op = Dests[DestSize - 1];
+ Str << "\t"
+ "vpop"
+ "\t{";
+ for (SizeT i = 2; i <= DestSize; ++i) {
+ Operand *PreviousOp = Dests[DestSize - i];
+ if (!AssignedConsecutiveRegisters(PreviousOp, Op)) {
+ Dests[Start]->emit(Func);
+ for (SizeT j = Start + 1; j <= End; ++j) {
+ Str << ", ";
+ Dests[j]->emit(Func);
+ }
startNextInst(Func);
- NeedNewline = false;
+ Str << "}\n\t"
+ "vpop"
+ "\t{";
+ End = DestSize - i;
}
- Str << "\t"
- << "vpop"
- << "\t{";
- Op->emit(Func);
- Str << "}";
- NeedNewline = true;
+ Op = PreviousOp;
+ Start = DestSize - i;
+ }
+ Dests[Start]->emit(Func);
+ for (SizeT j = Start + 1; j <= End; ++j) {
+ Str << ", ";
+ Dests[j]->emit(Func);
}
- assert(NeedNewline); // caller will add the newline
+ Str << "}";
}
void InstARM32Pop::emitIAS(const Cfg *Func) const {
@@ -1256,7 +1308,7 @@ void InstARM32Pop::emitIAS(const Cfg *Func) const {
// Note: Can only apply pop register if single register is not sp.
assert((RegARM32::Encoded_Reg_sp != LastDest->getRegNum()) &&
"Effects of pop register SP is undefined!");
- // TODO(kschimpf) ARM sandbox does not allow the single register form of
+ // TODO(kschimpf): ARM sandbox does not allow the single register form of
// pop, and the popList form expects multiple registers. Convert this
// assert to a conditional check once it has been shown that popList
// works.
@@ -1289,53 +1341,48 @@ void InstARM32Push::emit(const Cfg *Func) const {
// TODO(jpp): Improve FP register save/restore.
if (!BuildDefs::dump())
return;
- SizeT IntegerCount = 0;
- for (SizeT i = 0; i < getSrcSize(); ++i) {
- if (isScalarIntegerType(getSrc(i)->getType())) {
- ++IntegerCount;
- }
- }
Ostream &Str = Func->getContext()->getStrEmit();
- bool NeedNewline = false;
- for (SizeT i = getSrcSize(); i > 0; --i) {
- Operand *Op = getSrc(i - 1);
- if (isScalarIntegerType(Op->getType()))
- continue;
- if (NeedNewline) {
- Str << "\n";
- startNextInst(Func);
- NeedNewline = false;
- }
+ const SizeT SrcSize = getSrcSize();
+ assert(SrcSize > 0);
+ if (SrcSize == 0) {
+ return;
+ }
+
+ Operand *Op = getSrc(0);
+ if (isScalarIntegerType(Op->getType())) {
+ // GPR push.
Str << "\t"
- << "vpush"
- << "\t{";
+ "push"
+ "\t{";
Op->emit(Func);
+ for (SizeT i = 1; i < SrcSize; ++i) {
+ Str << ", ";
+ Op = getSrc(i);
+ Op->emit(Func);
+ }
Str << "}";
- NeedNewline = true;
+ return;
}
- if (IntegerCount != 0) {
- if (NeedNewline) {
- Str << "\n";
+
+ // VFP "s" reg push.
+ Str << "\t"
+ "vpush"
+ "\t{";
+ Op->emit(Func);
+ for (SizeT i = 1; i < SrcSize; ++i) {
+ Operand *NextOp = getSrc(i);
+ if (AssignedConsecutiveRegisters(Op, NextOp)) {
+ Str << ", ";
+ } else {
startNextInst(Func);
- NeedNewline = false;
- }
- Str << "\t"
- << "push"
- << "\t{";
- bool PrintComma = false;
- for (SizeT i = 0; i < getSrcSize(); ++i) {
- Operand *Op = getSrc(i);
- if (isScalarIntegerType(Op->getType())) {
- if (PrintComma)
- Str << ", ";
- Op->emit(Func);
- PrintComma = true;
- }
+ Str << "}\n\t"
+ "vpush"
+ "\t{";
}
- Str << "}";
- NeedNewline = true;
+ Op = NextOp;
+ Op->emit(Func);
}
- assert(NeedNewline); // caller will add the newline
+ Str << "}";
}
void InstARM32Push::emitIAS(const Cfg *Func) const {
@@ -1892,8 +1939,10 @@ template class InstARM32ThreeAddrGPR<InstARM32::Udiv>;
template class InstARM32ThreeAddrFP<InstARM32::Vadd>;
template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
-template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
template class InstARM32ThreeAddrFP<InstARM32::Veor>;
+template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
+template class InstARM32ThreeAddrFP<InstARM32::Vmla>;
+template class InstARM32ThreeAddrFP<InstARM32::Vmls>;
template class InstARM32ThreeAddrFP<InstARM32::Vsub>;
template class InstARM32LoadBase<InstARM32::Ldr>;

Powered by Google App Engine
This is Rietveld 408576698