| Index: src/IceInstMIPS32.cpp
|
| diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp
|
| index 7773272a5985272e56e5bcc92009d015cd5f510a..7a4939a7b6006100f4e86133720275cc249f43bb 100644
|
| --- a/src/IceInstMIPS32.cpp
|
| +++ b/src/IceInstMIPS32.cpp
|
| @@ -12,7 +12,6 @@
|
| /// constructors and the dump()/emit() methods.
|
| ///
|
| //===----------------------------------------------------------------------===//
|
| -
|
| #include "IceAssemblerMIPS32.h"
|
| #include "IceCfg.h"
|
| #include "IceCfgNode.h"
|
| @@ -21,14 +20,62 @@
|
| #include "IceOperand.h"
|
| #include "IceRegistersMIPS32.h"
|
| #include "IceTargetLoweringMIPS32.h"
|
| +#include <limits>
|
|
|
| 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";
|
| }
|
|
|
| +
|
| +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 +93,25 @@ 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 InstMIPS32::emitUnaryopGPR(const char *Opcode, const InstMIPS32 *Inst,
|
| + const Cfg *Func) {
|
| + if (!BuildDefs::dump())
|
| + return;
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + // Type SrcTy = Inst->getSrc(0)->getType();
|
| + Str << "\t" << Opcode << "\t";
|
| + Inst->getDest()->emit(Func);
|
| + Str << ", ";
|
| + Inst->getSrc(0)->emit(Func);
|
| +}
|
| +
|
| void InstMIPS32Ret::emit(const Cfg *Func) const {
|
| if (!BuildDefs::dump())
|
| return;
|
| @@ -55,7 +121,7 @@ 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);
|
| }
|
| @@ -73,4 +139,102 @@ 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);
|
| +}
|
| +
|
| +} // end of namespace Ice
|
|
|