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

Unified Diff: src/IceInstARM32.cpp

Issue 1127963004: Subzero ARM: lowerArguments (GPR), basic legalize(), and lowerRet(i32, i64). (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fix warnings, etc Created 5 years, 7 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
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceInstARM32.def » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceInstARM32.cpp
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index 9f54e85a99f203ce42ef9d34b7cb45f41a86ecae..6ac169862b063dcb3149c765a8ef9c0977d7f182 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -37,12 +37,57 @@ const struct TypeARM32Attributes_ {
#undef X
};
+const struct InstARM32ShiftAttributes_ {
+ const char *EmitString;
+} InstARM32ShiftAttributes[] = {
+#define X(tag, emit) \
+ { emit } \
+ ,
+ ICEINSTARM32SHIFT_TABLE
+#undef X
+};
+
} // end of anonymous namespace
const char *InstARM32::getWidthString(Type Ty) {
return TypeARM32Attributes[Ty].WidthString;
}
+void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func) {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(Inst->getSrcSize() == 2);
+ Variable *Dest = Inst->getDest();
+ assert(Dest == Inst->getSrc(0));
+ Operand *Src1 = Inst->getSrc(1);
+ Str << "\t" << Opcode << "\t";
+ Dest->emit(Func);
+ Str << ", ";
+ Src1->emit(Func);
+}
+
+OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base,
+ ConstantInteger32 *ImmOffset, AddrMode Mode)
+ : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr),
+ ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) {
+ // The Neg modes are only needed for Reg +/- Reg.
+ assert(!isNegAddrMode());
+ NumVars = 1;
+ Vars = &this->Base;
+}
+
+OperandARM32Mem::OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base,
+ Variable *Index, ShiftKind ShiftOp,
+ uint16_t ShiftAmt, AddrMode Mode)
+ : OperandARM32(kMem, Ty), Base(Base), ImmOffset(0), Index(Index),
+ ShiftOp(ShiftOp), ShiftAmt(ShiftAmt), Mode(Mode) {
+ NumVars = 2;
+ Vars = Func->allocateArrayOf<Variable *>(2);
+ Vars[0] = Base;
+ Vars[1] = Index;
+}
+
bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits
: TypeARM32Attributes[Ty].ZExtAddrOffsetBits;
@@ -55,6 +100,52 @@ bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
return Utils::IsAbsoluteUint(Bits, Offset);
}
+OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty,
+ uint32_t Imm, uint32_t RotateAmt)
+ : OperandARM32Flex(kFlexImm, Ty), Imm(Imm), RotateAmt(RotateAmt) {
+ NumVars = 0;
+ Vars = nullptr;
+}
+
+bool OperandARM32FlexImm::canHoldImm(uint32_t Immediate, uint32_t *RotateAmt,
+ uint32_t *Immed_8) {
+ // Avoid the more expensive test for frequent small immediate values.
+ if (Immediate <= 0xFF) {
+ *RotateAmt = 0;
+ *Immed_8 = Immediate;
+ return true;
+ }
+ // Note that immediate must be unsigned for the test to work correctly.
+ for (int Rot = 1; Rot < 16; Rot++) {
+ uint32_t Imm8 = Utils::rotateLeft32(Immediate, 2 * Rot);
+ if (Imm8 <= 0xFF) {
+ *RotateAmt = Rot;
+ *Immed_8 = Imm8;
+ return true;
+ }
+ }
+ return false;
+}
+
+OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg,
+ ShiftKind ShiftOp, Operand *ShiftAmt)
+ : OperandARM32Flex(kFlexReg, Ty), Reg(Reg), ShiftOp(ShiftOp),
+ ShiftAmt(ShiftAmt) {
+ NumVars = 1;
+ Variable *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt);
+ if (ShiftVar)
+ ++NumVars;
+ Vars = Func->allocateArrayOf<Variable *>(NumVars);
+ Vars[0] = Reg;
+ if (ShiftVar)
+ Vars[1] = ShiftVar;
+}
+
+InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem)
+ : InstARM32(Func, InstARM32::Ldr, 1, Dest) {
+ addSource(Mem);
+}
+
InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
: InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) {
addSource(LR);
@@ -64,6 +155,14 @@ InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
// ======================== Dump routines ======================== //
+// Two-addr ops
+template <> const char *InstARM32Movt::Opcode = "movt";
+// Unary ops
+template <> const char *InstARM32Movw::Opcode = "movw";
+template <> const char *InstARM32Mvn::Opcode = "mvn";
+// Mov-like ops
+template <> const char *InstARM32Mov::Opcode = "mov";
+
void InstARM32::dump(const Cfg *Func) const {
if (!ALLOW_DUMP)
return;
@@ -72,6 +171,101 @@ void InstARM32::dump(const Cfg *Func) const {
Inst::dump(Func);
}
+template <> void InstARM32Mov::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 1);
+ Variable *Dest = getDest();
+ if (Dest->hasReg()) {
+ Str << "\t"
+ << "mov"
+ << "\t";
+ getDest()->emit(Func);
+ Str << ", ";
+ getSrc(0)->emit(Func);
+ } else {
+ Variable *Src0 = llvm::cast<Variable>(getSrc(0));
+ assert(Src0->hasReg());
+ Str << "\t"
+ << "str"
+ << "\t";
+ Src0->emit(Func);
+ Str << ", ";
+ Dest->emit(Func);
+ }
+}
+
+template <> void InstARM32Mov::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 1);
+ (void)Func;
+ llvm_unreachable("Not yet implemented");
+}
+
+void InstARM32Ldr::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 1);
+ assert(getDest()->hasReg());
+ Type Ty = getSrc(0)->getType();
+ Str << "\t"
+ << "ldr" << getWidthString(Ty) << "\t";
+ getDest()->emit(Func);
+ Str << ", ";
+ getSrc(0)->emit(Func);
+}
+
+void InstARM32Ldr::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 2);
+ (void)Func;
+ llvm_unreachable("Not yet implemented");
+}
+
+void InstARM32Ldr::dump(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrDump();
+ dumpDest(Func);
+ Str << "ldr." << getSrc(0)->getType() << " ";
+ dumpSources(Func);
+}
+
+template <> void InstARM32Movw::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 1);
+ Str << "\t" << Opcode << "\t";
+ getDest()->emit(Func);
+ Str << ", ";
+ Constant *Src0 = llvm::cast<Constant>(getSrc(0));
+ if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
+ Str << "#:lower16:";
+ CR->emitWithoutPrefix(Func->getTarget());
+ } else {
+ Src0->emit(Func);
+ }
+}
+
+template <> void InstARM32Movt::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 2);
+ Variable *Dest = getDest();
+ Constant *Src1 = llvm::cast<Constant>(getSrc(1));
+ Str << "\t" << Opcode << "\t";
+ Dest->emit(Func);
+ Str << ", ";
+ if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) {
+ Str << "#:upper16:";
+ CR->emitWithoutPrefix(Func->getTarget());
+ } else {
+ Src1->emit(Func);
+ }
+}
+
void InstARM32Ret::emit(const Cfg *Func) const {
if (!ALLOW_DUMP)
return;
@@ -98,4 +292,119 @@ void InstARM32Ret::dump(const Cfg *Func) const {
dumpSources(Func);
}
+void OperandARM32Mem::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ Str << "[";
+ getBase()->emit(Func);
+ switch (getAddrMode()) {
+ case PostIndex:
+ case NegPostIndex:
+ Str << "], ";
+ break;
+ default:
+ Str << ", ";
+ break;
+ }
+ if (isRegReg()) {
+ if (isNegAddrMode()) {
+ Str << "-";
+ }
+ getIndex()->emit(Func);
+ if (getShiftOp() != kNoShift) {
+ Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #"
+ << getShiftAmt();
+ }
+ } else {
+ getOffset()->emit(Func);
+ }
+ switch (getAddrMode()) {
+ case Offset:
+ case NegOffset:
+ Str << "]";
+ break;
+ case PreIndex:
+ case NegPreIndex:
+ Str << "]!";
+ break;
+ case PostIndex:
+ case NegPostIndex:
+ // Brace is already closed off.
+ break;
+ }
+}
+
+void OperandARM32Mem::dump(const Cfg *Func, Ostream &Str) const {
+ if (!ALLOW_DUMP)
+ return;
+ Str << "[";
+ if (Func)
+ getBase()->dump(Func);
+ else
+ getBase()->dump(Str);
+ Str << ", ";
+ if (isRegReg()) {
+ if (isNegAddrMode()) {
+ Str << "-";
+ }
+ if (Func)
+ getIndex()->dump(Func);
+ else
+ getIndex()->dump(Str);
+ if (getShiftOp() != kNoShift) {
+ Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #"
+ << getShiftAmt();
+ }
+ } else {
+ getOffset()->dump(Func, Str);
+ }
+ Str << "] AddrMode==" << getAddrMode() << "\n";
+}
+
+void OperandARM32FlexImm::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ uint32_t Imm = getImm();
+ uint32_t RotateAmt = getRotateAmt();
+ Str << "#" << Utils::rotateRight32(Imm, 2 * RotateAmt);
+}
+
+void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const {
+ if (!ALLOW_DUMP)
+ return;
+ uint32_t Imm = getImm();
+ uint32_t RotateAmt = getRotateAmt();
+ Str << "#(" << Imm << " ror 2*" << RotateAmt << ")";
+}
+
+void OperandARM32FlexReg::emit(const Cfg *Func) const {
+ if (!ALLOW_DUMP)
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ getReg()->emit(Func);
+ if (getShiftOp() != kNoShift) {
+ Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
+ getShiftAmt()->emit(Func);
+ }
+}
+
+void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const {
+ if (!ALLOW_DUMP)
+ return;
+ Variable *Reg = getReg();
+ if (Func)
+ Reg->dump(Func);
+ else
+ Reg->dump(Str);
+ if (getShiftOp() != kNoShift) {
+ Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
+ if (Func)
+ getShiftAmt()->dump(Func);
+ else
+ getShiftAmt()->dump(Str);
+ }
+}
+
} // end of namespace Ice
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceInstARM32.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698