Index: src/IceInstARM32.cpp |
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp |
index 6ac169862b063dcb3149c765a8ef9c0977d7f182..cd78df6aae9ecdc0e8c2c49336de30f4c99c7019 100644 |
--- a/src/IceInstARM32.cpp |
+++ b/src/IceInstARM32.cpp |
@@ -67,6 +67,23 @@ void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func) { |
Src1->emit(Func); |
} |
+void emitThreeAddr(const char *Opcode, const Inst *Inst, const Cfg *Func, |
+ bool SetFlags) { |
+ if (!ALLOW_DUMP) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(Inst->getSrcSize() == 2); |
+ Variable *Dest = Inst->getDest(); |
+ Operand *Src0 = Inst->getSrc(0); |
+ Operand *Src1 = Inst->getSrc(1); |
+ Str << "\t" << Opcode << (SetFlags ? "s" : "") << "\t"; |
+ Dest->emit(Func); |
+ Str << ", "; |
+ Src0->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), |
@@ -146,6 +163,14 @@ InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem) |
addSource(Mem); |
} |
+InstARM32Mla::InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, |
+ Variable *Src1, Variable *Acc) |
+ : InstARM32(Func, InstARM32::Mla, 3, Dest) { |
+ addSource(Src0); |
+ addSource(Src1); |
+ addSource(Acc); |
+} |
+ |
InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
: InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
addSource(LR); |
@@ -153,6 +178,15 @@ InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
addSource(Source); |
} |
+InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, |
+ Variable *Src0, Variable *Src1) |
+ : InstARM32(Func, InstARM32::Umull, 2, DestLo), |
+ // DestHi is expected to have a FakeDef inserted by the lowering code. |
+ DestHi(DestHi) { |
+ addSource(Src0); |
+ addSource(Src1); |
+} |
+ |
// ======================== Dump routines ======================== // |
// Two-addr ops |
@@ -162,6 +196,15 @@ template <> const char *InstARM32Movw::Opcode = "movw"; |
template <> const char *InstARM32Mvn::Opcode = "mvn"; |
// Mov-like ops |
template <> const char *InstARM32Mov::Opcode = "mov"; |
+// Three-addr ops |
+template <> const char *InstARM32Adc::Opcode = "adc"; |
+template <> const char *InstARM32Add::Opcode = "add"; |
+template <> const char *InstARM32And::Opcode = "and"; |
+template <> const char *InstARM32Eor::Opcode = "eor"; |
+template <> const char *InstARM32Mul::Opcode = "mul"; |
+template <> const char *InstARM32Orr::Opcode = "orr"; |
+template <> const char *InstARM32Sbc::Opcode = "sbc"; |
+template <> const char *InstARM32Sub::Opcode = "sub"; |
void InstARM32::dump(const Cfg *Func) const { |
if (!ALLOW_DUMP) |
@@ -217,7 +260,7 @@ void InstARM32Ldr::emit(const Cfg *Func) const { |
} |
void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
- assert(getSrcSize() == 2); |
+ assert(getSrcSize() == 1); |
(void)Func; |
llvm_unreachable("Not yet implemented"); |
} |
@@ -227,7 +270,40 @@ void InstARM32Ldr::dump(const Cfg *Func) const { |
return; |
Ostream &Str = Func->getContext()->getStrDump(); |
dumpDest(Func); |
- Str << "ldr." << getSrc(0)->getType() << " "; |
+ Str << " = ldr." << getSrc(0)->getType() << " "; |
+ dumpSources(Func); |
+} |
+ |
+void InstARM32Mla::emit(const Cfg *Func) const { |
+ if (!ALLOW_DUMP) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 3); |
+ assert(getDest()->hasReg()); |
+ Str << "\t" |
+ << "mla" |
+ << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ getSrc(0)->emit(Func); |
+ Str << ", "; |
+ getSrc(1)->emit(Func); |
+ Str << ", "; |
+ getSrc(2)->emit(Func); |
+} |
+ |
+void InstARM32Mla::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 3); |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+} |
+ |
+void InstARM32Mla::dump(const Cfg *Func) const { |
+ if (!ALLOW_DUMP) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ dumpDest(Func); |
+ Str << " = mla." << getSrc(0)->getType() << " "; |
dumpSources(Func); |
} |
@@ -274,7 +350,9 @@ void InstARM32Ret::emit(const Cfg *Func) const { |
assert(LR->hasReg()); |
assert(LR->getRegNum() == RegARM32::Reg_lr); |
Ostream &Str = Func->getContext()->getStrEmit(); |
- Str << "\tbx\t"; |
+ Str << "\t" |
+ << "bx" |
+ << "\t"; |
LR->emit(Func); |
} |
@@ -292,6 +370,39 @@ void InstARM32Ret::dump(const Cfg *Func) const { |
dumpSources(Func); |
} |
+void InstARM32Umull::emit(const Cfg *Func) const { |
+ if (!ALLOW_DUMP) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 2); |
+ assert(getDest()->hasReg()); |
+ Str << "\t" |
+ << "umull" |
+ << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ DestHi->emit(Func); |
+ Str << ", "; |
+ getSrc(0)->emit(Func); |
+ Str << ", "; |
+ getSrc(1)->emit(Func); |
+} |
+ |
+void InstARM32Umull::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 2); |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+} |
+ |
+void InstARM32Umull::dump(const Cfg *Func) const { |
+ if (!ALLOW_DUMP) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ dumpDest(Func); |
+ Str << " = umull." << getSrc(0)->getType() << " "; |
+ dumpSources(Func); |
+} |
+ |
void OperandARM32Mem::emit(const Cfg *Func) const { |
if (!ALLOW_DUMP) |
return; |