Chromium Code Reviews| Index: src/IceInstMIPS32.cpp |
| diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp |
| index 7773272a5985272e56e5bcc92009d015cd5f510a..cf5b710703fd0f216f765f9a37c48d50428c61c0 100644 |
| --- a/src/IceInstMIPS32.cpp |
| +++ b/src/IceInstMIPS32.cpp |
| @@ -12,7 +12,7 @@ |
| /// constructors and the dump()/emit() methods. |
| /// |
| //===----------------------------------------------------------------------===// |
| - |
| +#include <limits> |
|
Jim Stichnoth
2015/10/18 11:48:38
Generally our include order is:
#include "Ice*.h"
rkotlerimgtec
2015/10/19 00:11:59
Done.
|
| #include "IceAssemblerMIPS32.h" |
| #include "IceCfg.h" |
| #include "IceCfgNode.h" |
| @@ -24,11 +24,68 @@ |
| namespace Ice { |
| +bool OperandMIPS32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) { |
| + (void)SignExt; |
| + (void)Ty; |
| + if ((std::numeric_limits<int16_t>::min() <= Offset) && |
| + (Offset <= std::numeric_limits<int16_t>::max())) |
| + return true; |
| + return false; |
| +} |
| + |
| +OperandMIPS32Mem::OperandMIPS32Mem(Cfg *Func, Type Ty, Variable *Base, |
| + ConstantInteger32 *ImmOffset, AddrMode Mode) |
| + : OperandMIPS32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Mode(Mode) { |
| + // The Neg modes are only needed for Reg +/- Reg. |
| + (void)Func; |
| + // assert(!isNegAddrMode()); |
| + NumVars = 1; |
| + Vars = &this->Base; |
| +} |
| + |
| const char *InstMIPS32::getWidthString(Type Ty) { |
| (void)Ty; |
| return "TBD"; |
| } |
| +void InstMIPS32::emitUnaryopGPR(const char *Opcode, const InstMIPS32 *Inst, |
|
Jim Stichnoth
2015/10/18 11:48:37
Dump and textual emit routines usually go at the e
rkotlerimgtec
2015/10/19 00:11:59
Done.
|
| + const Cfg *Func) { |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
|
Jim Stichnoth
2015/10/18 11:48:37
Add the following to the beginning of all dump() a
rkotlerimgtec
2015/10/19 00:11:59
Done.
|
| + // assert(Inst->getSrcSize() == 1); |
|
Jim Stichnoth
2015/10/18 11:48:37
Don't leave commented-out code in the code base.
rkotlerimgtec
2015/10/19 00:11:59
Done.
|
| + // Type SrcTy = Inst->getSrc(0)->getType(); |
| + Str << "\t" << Opcode << "\t"; |
| + Inst->getDest()->emit(Func); |
| + Str << ", "; |
| + Inst->getSrc(0)->emit(Func); |
| +} |
| + |
| +template <> const char *InstMIPS32Addiu::Opcode = "addiu"; |
| +template <> const char *InstMIPS32Lui::Opcode = "lui"; |
| +template <> const char *InstMIPS32La::Opcode = "la"; |
| + |
| +template <> const char *InstMIPS32Ori::Opcode = "ori"; |
| + |
| +InstMIPS32Mov::InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src) |
| + : InstMIPS32(Func, InstMIPS32::Mov, 2, Dest) { |
| + auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest); |
| + auto *Src64 = llvm::dyn_cast<Variable64On32>(Src); |
| + |
| + assert(Dest64 == nullptr || Src64 == nullptr); |
| + |
| + if (Dest64 != nullptr) { |
| + // this-> is needed below because there is a parameter named Dest. |
| + this->Dest = Dest64->getLo(); |
| + DestHi = Dest64->getHi(); |
| + } |
| + |
| + if (Src64 == nullptr) { |
| + addSource(Src); |
| + } else { |
| + addSource(Src64->getLo()); |
| + addSource(Src64->getHi()); |
| + } |
| +} |
| + |
| InstMIPS32Ret::InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source) |
| : InstMIPS32(Func, InstMIPS32::Ret, Source ? 2 : 1, nullptr) { |
| addSource(RA); |
| @@ -46,6 +103,13 @@ void InstMIPS32::dump(const Cfg *Func) const { |
| Inst::dump(Func); |
| } |
| +void OperandMIPS32Mem::emit(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + llvm_unreachable("Not yet implemented"); |
| + (void)Func; |
| +} |
| + |
| void InstMIPS32Ret::emit(const Cfg *Func) const { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -55,9 +119,10 @@ void InstMIPS32Ret::emit(const Cfg *Func) const { |
| assert(RA->getRegNum() == RegMIPS32::Reg_RA); |
| Ostream &Str = Func->getContext()->getStrEmit(); |
| Str << "\t" |
| - << "jr $ra" |
| + << "jr" |
| << "\t"; |
| RA->emit(Func); |
| + Str << "\n"; |
|
Jim Stichnoth
2015/10/18 11:48:38
Usually the emit() routine doesn't print the endin
rkotlerimgtec
2015/10/19 00:11:59
Done.
|
| } |
| void InstMIPS32Ret::emitIAS(const Cfg *Func) const { |
| @@ -73,4 +138,101 @@ void InstMIPS32Ret::dump(const Cfg *Func) const { |
| Str << "ret." << Ty << " "; |
| dumpSources(Func); |
| } |
| + |
| +void InstMIPS32Mov::emit(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); |
| + if (isMultiDest()) { |
| + emitMultiDestSingleSource(Func); |
| + return; |
| + } |
| + |
| + if (isMultiSource()) { |
| + emitSingleDestMultiSource(Func); |
| + return; |
| + } |
| + |
| + emitSingleDestSingleSource(Func); |
| +} |
| + |
| +void InstMIPS32Mov::emitIAS(const Cfg *Func) const { |
| + assert(getSrcSize() == 1); |
| + (void)Func; |
| + llvm_unreachable("Not yet implemented"); |
| +} |
| + |
| +void InstMIPS32Mov::dump(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + assert(getSrcSize() == 1 || getSrcSize() == 2); |
| + Ostream &Str = Func->getContext()->getStrDump(); |
| + Variable *Dest = getDest(); |
| + Variable *DestHi = getDestHi(); |
| + Dest->dump(Func); |
| + if (DestHi) { |
| + Str << ", "; |
| + DestHi->dump(Func); |
| + } |
| + |
| + dumpOpcode(Str, " = mov", getDest()->getType()); |
| + Str << " "; |
| + |
| + dumpSources(Func); |
| +} |
| + |
| +void InstMIPS32Mov::emitMultiDestSingleSource(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
| + Variable *DestLo = getDest(); |
| + Variable *DestHi = getDestHi(); |
| + auto *Src = llvm::cast<Variable>(getSrc(0)); |
| + |
| + assert(DestHi->hasReg()); |
| + assert(DestLo->hasReg()); |
| + assert(llvm::isa<Variable>(Src) && Src->hasReg()); |
| + |
| + // Str << "\t" |
| + // << "vmov" << getPredicate() << "\t"; |
| + DestLo->emit(Func); |
| + Str << ", "; |
| + DestHi->emit(Func); |
| + Str << ", "; |
| + Src->emit(Func); |
| +} |
| + |
| +void InstMIPS32Mov::emitSingleDestMultiSource(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
| + Variable *Dest = getDest(); |
| + Variable *SrcLo = llvm::cast<Variable>(getSrc(0)); |
| + Variable *SrcHi = llvm::cast<Variable>(getSrc(1)); |
| + |
| + assert(SrcHi->hasReg()); |
| + assert(SrcLo->hasReg()); |
| + assert(Dest->hasReg()); |
| + assert(getSrcSize() == 2); |
| + |
| + // Str << "\t" |
| + // << "vmov" << getPredicate() << "\t"; |
| + Dest->emit(Func); |
| + Str << ", "; |
| + SrcLo->emit(Func); |
| + Str << ", "; |
| + SrcHi->emit(Func); |
| +} |
| + |
| +void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const { |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
| + // assert(Inst->getSrcSize() == 1); |
| + // Type SrcTy = Inst->getSrc(0)->getType(); |
| + Str << "\t" |
| + << "move" |
| + << "\t"; |
| + getDest()->emit(Func); |
| + Str << ", "; |
| + getSrc(0)->emit(Func); |
| +} |
| } |