//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements the TargetLoweringMIPS32 class, which consists almost
/// entirely of the lowering sequence for each high-level instruction.
///
//===----------------------------------------------------------------------===//

#include "IceTargetLoweringMIPS32.h"

#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceELFObjectWriter.h"
#include "IceGlobalInits.h"
#include "IceInstMIPS32.h"
#include "IceInstVarIter.h"
#include "IceLiveness.h"
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
#include "IceRegistersMIPS32.h"
#include "IceTargetLoweringMIPS32.def"
#include "IceUtils.h"
#include "llvm/Support/MathExtras.h"

namespace MIPS32 {
std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
  return ::Ice::MIPS32::TargetMIPS32::create(Func);
}

std::unique_ptr<::Ice::TargetDataLowering>
createTargetDataLowering(::Ice::GlobalContext *Ctx) {
  return ::Ice::MIPS32::TargetDataMIPS32::create(Ctx);
}

std::unique_ptr<::Ice::TargetHeaderLowering>
createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
  return ::Ice::MIPS32::TargetHeaderMIPS32::create(Ctx);
}

void staticInit(::Ice::GlobalContext *Ctx) {
  ::Ice::MIPS32::TargetMIPS32::staticInit(Ctx);
}

bool shouldBePooled(const ::Ice::Constant *C) {
  return ::Ice::MIPS32::TargetMIPS32::shouldBePooled(C);
}

::Ice::Type getPointerType() {
  return ::Ice::MIPS32::TargetMIPS32::getPointerType();
}

} // end of namespace MIPS32

namespace Ice {
namespace MIPS32 {

using llvm::isInt;

namespace {

// The maximum number of arguments to pass in GPR registers.
constexpr uint32_t MIPS32_MAX_GPR_ARG = 4;

std::array<RegNumT, MIPS32_MAX_GPR_ARG> GPRArgInitializer;
std::array<RegNumT, MIPS32_MAX_GPR_ARG / 2> I64ArgInitializer;

constexpr uint32_t MIPS32_MAX_FP_ARG = 2;

std::array<RegNumT, MIPS32_MAX_FP_ARG> FP32ArgInitializer;
std::array<RegNumT, MIPS32_MAX_FP_ARG> FP64ArgInitializer;

const char *getRegClassName(RegClass C) {
  auto ClassNum = static_cast<RegClassMIPS32>(C);
  assert(ClassNum < RCMIPS32_NUM);
  switch (ClassNum) {
  default:
    assert(C < RC_Target);
    return regClassString(C);
    // Add handling of new register classes below.
  }
}

// Stack alignment
constexpr uint32_t MIPS32_STACK_ALIGNMENT_BYTES = 16;

// Value is in bytes. Return Value adjusted to the next highest multiple of the
// stack alignment required for the given type.
uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) {
  size_t typeAlignInBytes = typeWidthInBytes(Ty);
  // Vectors are stored on stack with the same alignment as that of int type
  if (isVectorType(Ty))
    typeAlignInBytes = typeWidthInBytes(IceType_i32);
  return Utils::applyAlignment(Value, typeAlignInBytes);
}

// Value is in bytes. Return Value adjusted to the next highest multiple of the
// stack alignment.
uint32_t applyStackAlignment(uint32_t Value) {
  return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES);
}

} // end of anonymous namespace

TargetMIPS32::TargetMIPS32(Cfg *Func)
    : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) {}

void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables,
                                       size_t SpillAreaPaddingBytes,
                                       size_t SpillAreaSizeBytes,
                                       size_t GlobalsAndSubsequentPaddingSize) {
  const VariablesMetadata *VMetadata = Func->getVMetadata();
  size_t GlobalsSpaceUsed = SpillAreaPaddingBytes;
  size_t NextStackOffset = SpillAreaPaddingBytes;
  CfgVector<size_t> LocalsSize(Func->getNumNodes());
  const bool SimpleCoalescing = !callsReturnsTwice();
  for (Variable *Var : SortedSpilledVariables) {
    size_t Increment = typeWidthInBytesOnStack(Var->getType());
    if (SimpleCoalescing && VMetadata->isTracked(Var)) {
      if (VMetadata->isMultiBlock(Var)) {
        GlobalsSpaceUsed += Increment;
        NextStackOffset = GlobalsSpaceUsed;
      } else {
        SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex();
        LocalsSize[NodeIndex] += Increment;
        NextStackOffset = SpillAreaPaddingBytes +
                          GlobalsAndSubsequentPaddingSize +
                          LocalsSize[NodeIndex];
      }
    } else {
      NextStackOffset += Increment;
    }
    Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset);
  }
}

void TargetMIPS32::staticInit(GlobalContext *Ctx) {
  (void)Ctx;
  RegNumT::setLimit(RegMIPS32::Reg_NUM);
  SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM);
  SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM);
  SmallBitVector Float32Registers(RegMIPS32::Reg_NUM);
  SmallBitVector Float64Registers(RegMIPS32::Reg_NUM);
  SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM);
  SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM);
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
          isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
  IntegerRegisters[RegMIPS32::val] = isInt;                                    \
  I64PairRegisters[RegMIPS32::val] = isI64Pair;                                \
  Float32Registers[RegMIPS32::val] = isFP32;                                   \
  Float64Registers[RegMIPS32::val] = isFP64;                                   \
  VectorRegisters[RegMIPS32::val] = isVec128;                                  \
  RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM);                  \
  for (SizeT RegAlias : alias_init) {                                          \
    assert(!RegisterAliases[RegMIPS32::val][RegAlias] &&                       \
           "Duplicate alias for " #val);                                       \
    RegisterAliases[RegMIPS32::val].set(RegAlias);                             \
  }                                                                            \
  RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM);                  \
  assert(RegisterAliases[RegMIPS32::val][RegMIPS32::val]);
  REGMIPS32_TABLE;
#undef X

  // TODO(mohit.bhakkad): Change these inits once we provide argument related
  // field in register tables
  for (size_t i = 0; i < MIPS32_MAX_GPR_ARG; i++)
    GPRArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_A0 + i);

  for (size_t i = 0; i < MIPS32_MAX_GPR_ARG / 2; i++)
    I64ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_A0A1 + i);

  for (size_t i = 0; i < MIPS32_MAX_FP_ARG; i++) {
    FP32ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_F12 + i * 2);
    FP64ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_F12F13 + i);
  }

  TypeToRegisterSet[IceType_void] = InvalidRegisters;
  TypeToRegisterSet[IceType_i1] = IntegerRegisters;
  TypeToRegisterSet[IceType_i8] = IntegerRegisters;
  TypeToRegisterSet[IceType_i16] = IntegerRegisters;
  TypeToRegisterSet[IceType_i32] = IntegerRegisters;
  TypeToRegisterSet[IceType_i64] = IntegerRegisters;
  TypeToRegisterSet[IceType_f32] = Float32Registers;
  TypeToRegisterSet[IceType_f64] = Float64Registers;
  TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
  TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
  TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
  TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
  TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
  TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
  TypeToRegisterSet[IceType_v4f32] = VectorRegisters;

  for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i)
    TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i];

  filterTypeToRegisterSet(Ctx, RegMIPS32::Reg_NUM, TypeToRegisterSet,
                          llvm::array_lengthof(TypeToRegisterSet),
                          RegMIPS32::getRegName, getRegClassName);
}

void TargetMIPS32::unsetIfNonLeafFunc() {
  for (CfgNode *Node : Func->getNodes()) {
    for (Inst &Instr : Node->getInsts()) {
      if (llvm::isa<InstCall>(&Instr)) {
        // Unset MaybeLeafFunc if call instruction exists.
        MaybeLeafFunc = false;
        return;
      }
    }
  }
}

uint32_t TargetMIPS32::getStackAlignment() const {
  return MIPS32_STACK_ALIGNMENT_BYTES;
}

uint32_t TargetMIPS32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
  TargetMIPS32::CallingConv CC;
  RegNumT DummyReg;
  size_t OutArgsSizeBytes = 0;
  for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
    Operand *Arg = legalizeUndef(Call->getArg(i));
    const Type Ty = Arg->getType();
    RegNumT RegNum;
    if (CC.argInReg(Ty, i, &RegNum)) {
      continue;
    }

    OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty);
    OutArgsSizeBytes += typeWidthInBytesOnStack(Ty);
  }

  return applyStackAlignment(OutArgsSizeBytes);
}

namespace {
inline uint64_t getConstantMemoryOrder(Operand *Opnd) {
  if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
    return Integer->getValue();
  return Intrinsics::MemoryOrderInvalid;
}
}

void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) {
  constexpr bool NoTailCall = false;
  constexpr bool IsTargetHelperCall = true;
  Variable *Dest = Instr->getDest();
  const Type DestTy = Dest ? Dest->getType() : IceType_void;

  switch (Instr->getKind()) {
  default:
    return;
  case Inst::Select: {
    if (isVectorType(DestTy)) {
      Operand *SrcT = llvm::cast<InstSelect>(Instr)->getTrueOperand();
      Operand *SrcF = llvm::cast<InstSelect>(Instr)->getFalseOperand();
      Operand *Cond = llvm::cast<InstSelect>(Instr)->getCondition();
      Variable *T = Func->makeVariable(DestTy);
      auto *Undef = ConstantUndef::create(Ctx, DestTy);
      Context.insert<InstAssign>(T, Undef);
      auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T);
      VarVecOn32->initVecElement(Func);
      for (SizeT I = 0; I < typeNumElements(DestTy); ++I) {
        auto *Index = Ctx->getConstantInt32(I);
        auto *OpC = Func->makeVariable(typeElementType(Cond->getType()));
        Context.insert<InstExtractElement>(OpC, Cond, Index);
        auto *OpT = Func->makeVariable(typeElementType(DestTy));
        Context.insert<InstExtractElement>(OpT, SrcT, Index);
        auto *OpF = Func->makeVariable(typeElementType(DestTy));
        Context.insert<InstExtractElement>(OpF, SrcF, Index);
        auto *Dst = Func->makeVariable(typeElementType(DestTy));
        Variable *DestT = Func->makeVariable(DestTy);
        Context.insert<InstSelect>(Dst, OpC, OpT, OpF);
        Context.insert<InstInsertElement>(DestT, T, Dst, Index);
        T = DestT;
      }
      Context.insert<InstAssign>(Dest, T);
      Instr->setDeleted();
    }
    return;
  }
  case Inst::Fcmp: {
    if (isVectorType(DestTy)) {
      InstFcmp::FCond Cond = llvm::cast<InstFcmp>(Instr)->getCondition();
      Operand *Src0 = Instr->getSrc(0);
      Operand *Src1 = Instr->getSrc(1);
      Variable *T = Func->makeVariable(IceType_v4f32);
      auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32);
      Context.insert<InstAssign>(T, Undef);
      auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T);
      VarVecOn32->initVecElement(Func);
      for (SizeT I = 0; I < typeNumElements(IceType_v4f32); ++I) {
        auto *Index = Ctx->getConstantInt32(I);
        auto *Op0 = Func->makeVariable(IceType_f32);
        Context.insert<InstExtractElement>(Op0, Src0, Index);
        auto *Op1 = Func->makeVariable(IceType_f32);
        Context.insert<InstExtractElement>(Op1, Src1, Index);
        auto *Dst = Func->makeVariable(IceType_f32);
        Variable *DestT = Func->makeVariable(IceType_v4f32);
        Context.insert<InstFcmp>(Cond, Dst, Op0, Op1);
        Context.insert<InstInsertElement>(DestT, T, Dst, Index);
        T = DestT;
      }
      Context.insert<InstAssign>(Dest, T);
      Instr->setDeleted();
    }
    return;
  }
  case Inst::Icmp: {
    if (isVectorType(DestTy)) {
      InstIcmp::ICond Cond = llvm::cast<InstIcmp>(Instr)->getCondition();
      Operand *Src0 = Instr->getSrc(0);
      Operand *Src1 = Instr->getSrc(1);
      const Type SrcType = Src0->getType();
      Variable *T = Func->makeVariable(DestTy);
      auto *Undef = ConstantUndef::create(Ctx, DestTy);
      Context.insert<InstAssign>(T, Undef);
      auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T);
      VarVecOn32->initVecElement(Func);
      for (SizeT I = 0; I < typeNumElements(SrcType); ++I) {
        auto *Index = Ctx->getConstantInt32(I);
        auto *Op0 = Func->makeVariable(typeElementType(SrcType));
        Context.insert<InstExtractElement>(Op0, Src0, Index);
        auto *Op1 = Func->makeVariable(typeElementType(SrcType));
        Context.insert<InstExtractElement>(Op1, Src1, Index);
        auto *Dst = Func->makeVariable(typeElementType(DestTy));
        Variable *DestT = Func->makeVariable(DestTy);
        Context.insert<InstIcmp>(Cond, Dst, Op0, Op1);
        Context.insert<InstInsertElement>(DestT, T, Dst, Index);
        T = DestT;
      }
      Context.insert<InstAssign>(Dest, T);
      Instr->setDeleted();
    }
    return;
  }
  case Inst::Arithmetic: {
    const InstArithmetic::OpKind Op =
        llvm::cast<InstArithmetic>(Instr)->getOp();
    if (isVectorType(DestTy)) {
      scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1));
      Instr->setDeleted();
      return;
    }
    switch (DestTy) {
    default:
      return;
    case IceType_i64: {
      RuntimeHelper HelperID = RuntimeHelper::H_Num;
      switch (Op) {
      default:
        return;
      case InstArithmetic::Udiv:
        HelperID = RuntimeHelper::H_udiv_i64;
        break;
      case InstArithmetic::Sdiv:
        HelperID = RuntimeHelper::H_sdiv_i64;
        break;
      case InstArithmetic::Urem:
        HelperID = RuntimeHelper::H_urem_i64;
        break;
      case InstArithmetic::Srem:
        HelperID = RuntimeHelper::H_srem_i64;
        break;
      }

      if (HelperID == RuntimeHelper::H_Num) {
        return;
      }

      Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID);
      constexpr SizeT MaxArgs = 2;
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(Instr->getSrc(0));
      Call->addArg(Instr->getSrc(1));
      Instr->setDeleted();
      return;
    }
    case IceType_f32:
    case IceType_f64: {
      if (Op != InstArithmetic::Frem) {
        return;
      }
      constexpr SizeT MaxArgs = 2;
      Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
          DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32
                                : RuntimeHelper::H_frem_f64);
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(Instr->getSrc(0));
      Call->addArg(Instr->getSrc(1));
      Instr->setDeleted();
      return;
    }
    }
    llvm::report_fatal_error("Control flow should never have reached here.");
  }
  case Inst::Cast: {
    Operand *Src0 = Instr->getSrc(0);
    const Type SrcTy = Src0->getType();
    auto *CastInstr = llvm::cast<InstCast>(Instr);
    const InstCast::OpKind CastKind = CastInstr->getCastKind();

    if (isVectorType(DestTy)) {
      Variable *T = Func->makeVariable(DestTy);
      auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T);
      VarVecOn32->initVecElement(Func);
      auto *Undef = ConstantUndef::create(Ctx, DestTy);
      Context.insert<InstAssign>(T, Undef);
      for (SizeT I = 0; I < typeNumElements(DestTy); ++I) {
        auto *Index = Ctx->getConstantInt32(I);
        auto *Op = Func->makeVariable(typeElementType(SrcTy));
        Context.insert<InstExtractElement>(Op, Src0, Index);
        auto *Dst = Func->makeVariable(typeElementType(DestTy));
        Variable *DestT = Func->makeVariable(DestTy);
        Context.insert<InstCast>(CastKind, Dst, Op);
        Context.insert<InstInsertElement>(DestT, T, Dst, Index);
        T = DestT;
      }
      Context.insert<InstAssign>(Dest, T);
      Instr->setDeleted();
      return;
    }

    switch (CastKind) {
    default:
      return;
    case InstCast::Fptosi:
    case InstCast::Fptoui: {
      if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) {
        return;
      }
      const bool DestIs32 = DestTy == IceType_i32;
      const bool DestIsSigned = CastKind == InstCast::Fptosi;
      const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy);
      RuntimeHelper RTHFunc = RuntimeHelper::H_Num;
      if (DestIsSigned) {
        if (DestIs32) {
          return;
        }
        RTHFunc = Src0IsF32 ? RuntimeHelper::H_fptosi_f32_i64
                            : RuntimeHelper::H_fptosi_f64_i64;
      } else {
        RTHFunc = Src0IsF32 ? (DestIs32 ? RuntimeHelper::H_fptoui_f32_i32
                                        : RuntimeHelper::H_fptoui_f32_i64)
                            : (DestIs32 ? RuntimeHelper::H_fptoui_f64_i32
                                        : RuntimeHelper::H_fptoui_f64_i64);
      }
      Operand *TargetHelper = Ctx->getRuntimeHelperFunc(RTHFunc);
      static constexpr SizeT MaxArgs = 1;
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(Src0);
      Instr->setDeleted();
      return;
    }
    case InstCast::Sitofp:
    case InstCast::Uitofp: {
      if ((SrcTy != IceType_i32) && (SrcTy != IceType_i64)) {
        return;
      }
      const bool SourceIs32 = SrcTy == IceType_i32;
      const bool SourceIsSigned = CastKind == InstCast::Sitofp;
      const bool DestIsF32 = isFloat32Asserting32Or64(DestTy);
      RuntimeHelper RTHFunc = RuntimeHelper::H_Num;
      if (SourceIsSigned) {
        if (SourceIs32) {
          return;
        }
        RTHFunc = DestIsF32 ? RuntimeHelper::H_sitofp_i64_f32
                            : RuntimeHelper::H_sitofp_i64_f64;
      } else {
        RTHFunc = DestIsF32 ? (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f32
                                          : RuntimeHelper::H_uitofp_i64_f32)
                            : (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f64
                                          : RuntimeHelper::H_uitofp_i64_f64);
      }
      Operand *TargetHelper = Ctx->getRuntimeHelperFunc(RTHFunc);
      static constexpr SizeT MaxArgs = 1;
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(Src0);
      Instr->setDeleted();
      return;
    }
    case InstCast::Bitcast: {
      if (DestTy == SrcTy) {
        return;
      }
      Variable *CallDest = Dest;
      RuntimeHelper HelperID = RuntimeHelper::H_Num;
      switch (DestTy) {
      default:
        return;
      case IceType_i8:
        assert(SrcTy == IceType_v8i1);
        HelperID = RuntimeHelper::H_bitcast_8xi1_i8;
        CallDest = Func->makeVariable(IceType_i32);
        break;
      case IceType_i16:
        assert(SrcTy == IceType_v16i1);
        HelperID = RuntimeHelper::H_bitcast_16xi1_i16;
        CallDest = Func->makeVariable(IceType_i32);
        break;
      case IceType_v8i1: {
        assert(SrcTy == IceType_i8);
        HelperID = RuntimeHelper::H_bitcast_i8_8xi1;
        Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
        // Arguments to functions are required to be at least 32 bits wide.
        Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
        Src0 = Src0AsI32;
      } break;
      case IceType_v16i1: {
        assert(SrcTy == IceType_i16);
        HelperID = RuntimeHelper::H_bitcast_i16_16xi1;
        Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
        // Arguments to functions are required to be at least 32 bits wide.
        Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
        Src0 = Src0AsI32;
      } break;
      }
      constexpr SizeT MaxSrcs = 1;
      InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs);
      Call->addArg(Src0);
      Context.insert(Call);
      // The PNaCl ABI disallows i8/i16 return types, so truncate the helper
      // call result to the appropriate type as necessary.
      if (CallDest->getType() != DestTy)
        Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest);
      Instr->setDeleted();
      return;
    }
    case InstCast::Trunc: {
      if (DestTy == SrcTy) {
        return;
      }
      if (!isVectorType(SrcTy)) {
        return;
      }
      assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
      assert(typeElementType(DestTy) == IceType_i1);
      assert(isVectorIntegerType(SrcTy));
      return;
    }
    case InstCast::Sext:
    case InstCast::Zext: {
      if (DestTy == SrcTy) {
        return;
      }
      if (!isVectorType(DestTy)) {
        return;
      }
      assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
      assert(typeElementType(SrcTy) == IceType_i1);
      assert(isVectorIntegerType(DestTy));
      return;
    }
    }
    llvm::report_fatal_error("Control flow should never have reached here.");
  }
  case Inst::IntrinsicCall: {
    auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr);
    Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID;
    if (isVectorType(DestTy) && ID == Intrinsics::Fabs) {
      Operand *Src0 = IntrinsicCall->getArg(0);
      GlobalString FabsFloat = Ctx->getGlobalString("llvm.fabs.f32");
      Operand *CallTarget = Ctx->getConstantExternSym(FabsFloat);
      GlobalString FabsVec = Ctx->getGlobalString("llvm.fabs.v4f32");
      bool BadIntrinsic = false;
      const Intrinsics::FullIntrinsicInfo *FullInfo =
          Ctx->getIntrinsicsInfo().find(FabsVec, BadIntrinsic);
      Intrinsics::IntrinsicInfo Info = FullInfo->Info;

      Variable *T = Func->makeVariable(IceType_v4f32);
      auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32);
      Context.insert<InstAssign>(T, Undef);
      auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T);
      VarVecOn32->initVecElement(Func);

      for (SizeT i = 0; i < typeNumElements(IceType_v4f32); ++i) {
        auto *Index = Ctx->getConstantInt32(i);
        auto *Op = Func->makeVariable(IceType_f32);
        Context.insert<InstExtractElement>(Op, Src0, Index);
        auto *Res = Func->makeVariable(IceType_f32);
        Variable *DestT = Func->makeVariable(IceType_v4f32);
        auto *Call =
            Context.insert<InstIntrinsicCall>(1, Res, CallTarget, Info);
        Call->addArg(Op);
        Context.insert<InstInsertElement>(DestT, T, Res, Index);
        T = DestT;
      }

      Context.insert<InstAssign>(Dest, T);

      Instr->setDeleted();
      return;
    }
    switch (ID) {
    default:
      return;
    case Intrinsics::Ctpop: {
      Operand *Src0 = IntrinsicCall->getArg(0);
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(isInt32Asserting32Or64(Src0->getType())
                                        ? RuntimeHelper::H_call_ctpop_i32
                                        : RuntimeHelper::H_call_ctpop_i64);
      static constexpr SizeT MaxArgs = 1;
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(Src0);
      Instr->setDeleted();
      return;
    }
    case Intrinsics::Longjmp: {
      static constexpr SizeT MaxArgs = 2;
      static constexpr Variable *NoDest = nullptr;
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_longjmp);
      auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(IntrinsicCall->getArg(0));
      Call->addArg(IntrinsicCall->getArg(1));
      Instr->setDeleted();
      return;
    }
    case Intrinsics::Memcpy: {
      static constexpr SizeT MaxArgs = 3;
      static constexpr Variable *NoDest = nullptr;
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memcpy);
      auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(IntrinsicCall->getArg(0));
      Call->addArg(IntrinsicCall->getArg(1));
      Call->addArg(IntrinsicCall->getArg(2));
      Instr->setDeleted();
      return;
    }
    case Intrinsics::Memmove: {
      static constexpr SizeT MaxArgs = 3;
      static constexpr Variable *NoDest = nullptr;
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memmove);
      auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(IntrinsicCall->getArg(0));
      Call->addArg(IntrinsicCall->getArg(1));
      Call->addArg(IntrinsicCall->getArg(2));
      Instr->setDeleted();
      return;
    }
    case Intrinsics::Memset: {
      Operand *ValOp = IntrinsicCall->getArg(1);
      assert(ValOp->getType() == IceType_i8);
      Variable *ValExt = Func->makeVariable(stackSlotType());
      Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp);

      static constexpr SizeT MaxArgs = 3;
      static constexpr Variable *NoDest = nullptr;
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memset);
      auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(IntrinsicCall->getArg(0));
      Call->addArg(ValExt);
      Call->addArg(IntrinsicCall->getArg(2));
      Instr->setDeleted();
      return;
    }
    case Intrinsics::NaClReadTP: {
      if (SandboxingType == ST_NaCl) {
        return;
      }
      static constexpr SizeT MaxArgs = 0;
      assert(SandboxingType != ST_Nonsfi);
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_read_tp);
      Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall,
                               IsTargetHelperCall);
      Instr->setDeleted();
      return;
    }
    case Intrinsics::Setjmp: {
      static constexpr SizeT MaxArgs = 1;
      Operand *TargetHelper =
          Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_setjmp);
      auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
                                            NoTailCall, IsTargetHelperCall);
      Call->addArg(IntrinsicCall->getArg(0));
      Instr->setDeleted();
      return;
    }
    }
    llvm::report_fatal_error("Control flow should never have reached here.");
  }
  }
}

void TargetMIPS32::findMaxStackOutArgsSize() {
  // MinNeededOutArgsBytes should be updated if the Target ever creates a
  // high-level InstCall that requires more stack bytes.
  size_t MinNeededOutArgsBytes = 0;
  if (!MaybeLeafFunc)
    MinNeededOutArgsBytes = MIPS32_MAX_GPR_ARG * 4;
  MaxOutArgsSizeBytes = MinNeededOutArgsBytes;
  for (CfgNode *Node : Func->getNodes()) {
    Context.init(Node);
    while (!Context.atEnd()) {
      PostIncrLoweringContext PostIncrement(Context);
      Inst *CurInstr = iteratorToInst(Context.getCur());
      if (auto *Call = llvm::dyn_cast<InstCall>(CurInstr)) {
        SizeT OutArgsSizeBytes = getCallStackArgumentsSizeBytes(Call);
        MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, OutArgsSizeBytes);
      }
    }
  }
  CurrentAllocaOffset = MaxOutArgsSizeBytes;
}

void TargetMIPS32::translateO2() {
  TimerMarker T(TimerStack::TT_O2, Func);

  // TODO(stichnot): share passes with X86?
  // https://code.google.com/p/nativeclient/issues/detail?id=4094
  genTargetHelperCalls();

  unsetIfNonLeafFunc();

  findMaxStackOutArgsSize();

  // Merge Alloca instructions, and lay out the stack.
  static constexpr bool SortAndCombineAllocas = true;
  Func->processAllocas(SortAndCombineAllocas);
  Func->dump("After Alloca processing");

  if (!getFlags().getEnablePhiEdgeSplit()) {
    // Lower Phi instructions.
    Func->placePhiLoads();
    if (Func->hasError())
      return;
    Func->placePhiStores();
    if (Func->hasError())
      return;
    Func->deletePhis();
    if (Func->hasError())
      return;
    Func->dump("After Phi lowering");
  }

  // Address mode optimization.
  Func->getVMetadata()->init(VMK_SingleDefs);
  Func->doAddressOpt();

  // Argument lowering
  Func->doArgLowering();

  // Target lowering. This requires liveness analysis for some parts of the
  // lowering decisions, such as compare/branch fusing. If non-lightweight
  // liveness analysis is used, the instructions need to be renumbered first.
  // TODO: This renumbering should only be necessary if we're actually
  // calculating live intervals, which we only do for register allocation.
  Func->renumberInstructions();
  if (Func->hasError())
    return;

  // TODO: It should be sufficient to use the fastest liveness calculation,
  // i.e. livenessLightweight(). However, for some reason that slows down the
  // rest of the translation. Investigate.
  Func->liveness(Liveness_Basic);
  if (Func->hasError())
    return;
  Func->dump("After MIPS32 address mode opt");

  Func->genCode();
  if (Func->hasError())
    return;
  Func->dump("After MIPS32 codegen");

  // Register allocation. This requires instruction renumbering and full
  // liveness analysis.
  Func->renumberInstructions();
  if (Func->hasError())
    return;
  Func->liveness(Liveness_Intervals);
  if (Func->hasError())
    return;
  // The post-codegen dump is done here, after liveness analysis and associated
  // cleanup, to make the dump cleaner and more useful.
  Func->dump("After initial MIPS32 codegen");
  // Validate the live range computations. The expensive validation call is
  // deliberately only made when assertions are enabled.
  assert(Func->validateLiveness());
  Func->getVMetadata()->init(VMK_All);
  regAlloc(RAK_Global);
  if (Func->hasError())
    return;
  Func->dump("After linear scan regalloc");

  if (getFlags().getEnablePhiEdgeSplit()) {
    Func->advancedPhiLowering();
    Func->dump("After advanced Phi lowering");
  }

  // Stack frame mapping.
  Func->genFrame();
  if (Func->hasError())
    return;
  Func->dump("After stack frame mapping");

  postLowerLegalization();
  if (Func->hasError())
    return;
  Func->dump("After postLowerLegalization");

  Func->contractEmptyNodes();
  Func->reorderNodes();

  // Branch optimization. This needs to be done just before code emission. In
  // particular, no transformations that insert or reorder CfgNodes should be
  // done after branch optimization. We go ahead and do it before nop insertion
  // to reduce the amount of work needed for searching for opportunities.
  Func->doBranchOpt();
  Func->dump("After branch optimization");

  // Nop insertion
  if (getFlags().getShouldDoNopInsertion()) {
    Func->doNopInsertion();
  }
}

void TargetMIPS32::translateOm1() {
  TimerMarker T(TimerStack::TT_Om1, Func);

  // TODO: share passes with X86?
  genTargetHelperCalls();

  unsetIfNonLeafFunc();

  findMaxStackOutArgsSize();

  // Do not merge Alloca instructions, and lay out the stack.
  static constexpr bool SortAndCombineAllocas = false;
  Func->processAllocas(SortAndCombineAllocas);
  Func->dump("After Alloca processing");

  Func->placePhiLoads();
  if (Func->hasError())
    return;
  Func->placePhiStores();
  if (Func->hasError())
    return;
  Func->deletePhis();
  if (Func->hasError())
    return;
  Func->dump("After Phi lowering");

  Func->doArgLowering();

  Func->genCode();
  if (Func->hasError())
    return;
  Func->dump("After initial MIPS32 codegen");

  regAlloc(RAK_InfOnly);
  if (Func->hasError())
    return;
  Func->dump("After regalloc of infinite-weight variables");

  Func->genFrame();
  if (Func->hasError())
    return;
  Func->dump("After stack frame mapping");

  postLowerLegalization();
  if (Func->hasError())
    return;
  Func->dump("After postLowerLegalization");

  // Nop insertion
  if (getFlags().getShouldDoNopInsertion()) {
    Func->doNopInsertion();
  }
}

bool TargetMIPS32::doBranchOpt(Inst *Instr, const CfgNode *NextNode) {
  if (auto *Br = llvm::dyn_cast<InstMIPS32Br>(Instr)) {
    return Br->optimizeBranch(NextNode);
  }
  return false;
}

namespace {

const char *RegNames[RegMIPS32::Reg_NUM] = {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
          isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
  name,
    REGMIPS32_TABLE
#undef X
};

} // end of anonymous namespace

const char *RegMIPS32::getRegName(RegNumT RegNum) {
  RegNum.assertIsValid();
  return RegNames[RegNum];
}

const char *TargetMIPS32::getRegName(RegNumT RegNum, Type Ty) const {
  (void)Ty;
  return RegMIPS32::getRegName(RegNum);
}

Variable *TargetMIPS32::getPhysicalRegister(RegNumT RegNum, Type Ty) {
  if (Ty == IceType_void)
    Ty = IceType_i32;
  if (PhysicalRegisters[Ty].empty())
    PhysicalRegisters[Ty].resize(RegMIPS32::Reg_NUM);
  RegNum.assertIsValid();
  Variable *Reg = PhysicalRegisters[Ty][RegNum];
  if (Reg == nullptr) {
    Reg = Func->makeVariable(Ty);
    Reg->setRegNum(RegNum);
    PhysicalRegisters[Ty][RegNum] = Reg;
    // Specially mark a named physical register as an "argument" so that it is
    // considered live upon function entry.  Otherwise it's possible to get
    // liveness validation errors for saving callee-save registers.
    Func->addImplicitArg(Reg);
    // Don't bother tracking the live range of a named physical register.
    Reg->setIgnoreLiveness();
  }
  return Reg;
}

void TargetMIPS32::emitJumpTable(const Cfg *Func,
                                 const InstJumpTable *JumpTable) const {
  (void)Func;
  (void)JumpTable;
  UnimplementedError(getFlags());
}

/// Provide a trivial wrapper to legalize() for this common usage.
Variable *TargetMIPS32::legalizeToReg(Operand *From, RegNumT RegNum) {
  return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
}

/// Legalize undef values to concrete values.
Operand *TargetMIPS32::legalizeUndef(Operand *From, RegNumT RegNum) {
  (void)RegNum;
  Type Ty = From->getType();
  if (llvm::isa<ConstantUndef>(From)) {
    // Lower undefs to zero.  Another option is to lower undefs to an
    // uninitialized register; however, using an uninitialized register
    // results in less predictable code.
    //
    // If in the future the implementation is changed to lower undef
    // values to uninitialized registers, a FakeDef will be needed:
    //     Context.insert(InstFakeDef::create(Func, Reg));
    // This is in order to ensure that the live range of Reg is not
    // overestimated.  If the constant being lowered is a 64 bit value,
    // then the result should be split and the lo and hi components will
    // need to go in uninitialized registers.
    if (isVectorType(Ty)) {
      Variable *Var = makeReg(Ty, RegNum);
      auto *Reg = llvm::cast<VariableVecOn32>(Var);
      Reg->initVecElement(Func);
      auto *Zero = getZero();
      Context.insert<InstFakeDef>(Zero);
      for (Variable *Var : Reg->getContainers()) {
        _mov(Var, Zero);
      }
      return Reg;
    }
    return Ctx->getConstantZero(Ty);
  }
  return From;
}

Variable *TargetMIPS32::makeReg(Type Type, RegNumT RegNum) {
  // There aren't any 64-bit integer registers for Mips32.
  assert(Type != IceType_i64);
  Variable *Reg = Func->makeVariable(Type);
  if (RegNum.hasValue())
    Reg->setRegNum(RegNum);
  else
    Reg->setMustHaveReg();
  return Reg;
}

OperandMIPS32Mem *TargetMIPS32::formMemoryOperand(Operand *Operand, Type Ty) {
  // It may be the case that address mode optimization already creates an
  // OperandMIPS32Mem, so in that case it wouldn't need another level of
  // transformation.
  if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
    return llvm::cast<OperandMIPS32Mem>(legalize(Mem));
  }

  // If we didn't do address mode optimization, then we only have a base/offset
  // to work with. MIPS always requires a base register, so just use that to
  // hold the operand.
  auto *Base = llvm::cast<Variable>(
      legalize(Operand, Legal_Reg | Legal_Rematerializable));
  const int32_t Offset = Base->hasStackOffset() ? Base->getStackOffset() : 0;
  return OperandMIPS32Mem::create(
      Func, Ty, Base,
      llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(Offset)));
}

void TargetMIPS32::emitVariable(const Variable *Var) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Ctx->getStrEmit();
  const Type FrameSPTy = IceType_i32;
  if (Var->hasReg()) {
    Str << '$' << getRegName(Var->getRegNum(), Var->getType());
    return;
  }
  if (Var->mustHaveReg()) {
    llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
                             ") has no register assigned - function " +
                             Func->getFunctionName());
  }
  const int32_t Offset = Var->getStackOffset();
  Str << Offset;
  Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy);
  Str << ")";
}

TargetMIPS32::CallingConv::CallingConv()
    : GPRegsUsed(RegMIPS32::Reg_NUM),
      GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
      I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
      VFPRegsUsed(RegMIPS32::Reg_NUM),
      FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
      FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()) {}

// In MIPS O32 abi FP argument registers can be used only if first argument is
// of type float/double. UseFPRegs flag is used to care of that. Also FP arg
// registers can be used only for first 2 arguments, so we require argument
// number to make register allocation decisions.
bool TargetMIPS32::CallingConv::argInReg(Type Ty, uint32_t ArgNo,
                                         RegNumT *Reg) {
  if (isScalarIntegerType(Ty) || isVectorType(Ty))
    return argInGPR(Ty, Reg);
  if (isScalarFloatingType(Ty)) {
    if (ArgNo == 0) {
      UseFPRegs = true;
      return argInVFP(Ty, Reg);
    }
    if (UseFPRegs && ArgNo == 1) {
      UseFPRegs = false;
      return argInVFP(Ty, Reg);
    }
    return argInGPR(Ty, Reg);
  }
  llvm::report_fatal_error("argInReg: Invalid type.");
  return false;
}

bool TargetMIPS32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) {
  CfgVector<RegNumT> *Source;

  switch (Ty) {
  default: {
    llvm::report_fatal_error("argInGPR: Invalid type.");
    return false;
  } break;
  case IceType_v4i1:
  case IceType_v8i1:
  case IceType_v16i1:
  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
  case IceType_v4f32:
  case IceType_i32:
  case IceType_f32: {
    Source = &GPRArgs;
  } break;
  case IceType_i64:
  case IceType_f64: {
    Source = &I64Args;
  } break;
  }

  discardUnavailableGPRsAndTheirAliases(Source);

  // If $4 is used for any scalar type (or returining v4f32) then the next
  // vector type if passed in $6:$7:stack:stack
  if (isVectorType(Ty)) {
    alignGPR(Source);
  }

  if (Source->empty()) {
    GPRegsUsed.set();
    return false;
  }

  *Reg = Source->back();
  // Note that we don't Source->pop_back() here. This is intentional. Notice how
  // we mark all of Reg's aliases as Used. So, for the next argument,
  // Source->back() is marked as unavailable, and it is thus implicitly popped
  // from the stack.
  GPRegsUsed |= RegisterAliases[*Reg];

  // All vector arguments irrespective of their base type are passed in GP
  // registers. First vector argument is passed in $4:$5:$6:$7 and 2nd
  // is passed in $6:$7:stack:stack. If it is 1st argument then discard
  // $4:$5:$6:$7 otherwise discard $6:$7 only.
  if (isVectorType(Ty)) {
    if (((unsigned)*Reg) == RegMIPS32::Reg_A0) {
      GPRegsUsed |= RegisterAliases[RegMIPS32::Reg_A1];
      GPRegsUsed |= RegisterAliases[RegMIPS32::Reg_A2];
      GPRegsUsed |= RegisterAliases[RegMIPS32::Reg_A3];
    } else {
      GPRegsUsed |= RegisterAliases[RegMIPS32::Reg_A3];
    }
  }

  return true;
}

inline void TargetMIPS32::CallingConv::discardNextGPRAndItsAliases(
    CfgVector<RegNumT> *Regs) {
  GPRegsUsed |= RegisterAliases[Regs->back()];
  Regs->pop_back();
}

inline void TargetMIPS32::CallingConv::alignGPR(CfgVector<RegNumT> *Regs) {
  if (Regs->back() == RegMIPS32::Reg_A1 || Regs->back() == RegMIPS32::Reg_A3)
    discardNextGPRAndItsAliases(Regs);
}

// GPR are not packed when passing parameters. Thus, a function foo(i32, i64,
// i32) will have the first argument in a0, the second in a2-a3, and the third
// on the stack. To model this behavior, whenever we pop a register from Regs,
// we remove all of its aliases from the pool of available GPRs. This has the
// effect of computing the "closure" on the GPR registers.
void TargetMIPS32::CallingConv::discardUnavailableGPRsAndTheirAliases(
    CfgVector<RegNumT> *Regs) {
  while (!Regs->empty() && GPRegsUsed[Regs->back()]) {
    discardNextGPRAndItsAliases(Regs);
  }
}

bool TargetMIPS32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) {
  CfgVector<RegNumT> *Source;

  switch (Ty) {
  default: {
    llvm::report_fatal_error("argInVFP: Invalid type.");
    return false;
  } break;
  case IceType_f32: {
    Source = &FP32Args;
  } break;
  case IceType_f64: {
    Source = &FP64Args;
  } break;
  }

  discardUnavailableVFPRegsAndTheirAliases(Source);

  if (Source->empty()) {
    VFPRegsUsed.set();
    return false;
  }

  *Reg = Source->back();
  VFPRegsUsed |= RegisterAliases[*Reg];

  // In MIPS O32 abi if fun arguments are (f32, i32) then one can not use reg_a0
  // for second argument even though it's free. f32 arg goes in reg_f12, i32 arg
  // goes in reg_a1. Similarly if arguments are (f64, i32) second argument goes
  // in reg_a3 and a0, a1 are not used.
  Source = &GPRArgs;
  // Discard one GPR reg for f32(4 bytes), two for f64(4 + 4 bytes)
  if (Ty == IceType_f64) {
    // In MIPS o32 abi, when we use GPR argument pairs to store F64 values, pair
    // must be aligned at even register. Similarly when we discard GPR registers
    // when some arguments from starting 16 bytes goes in FPR, we must take care
    // of alignment. For example if fun args are (f32, f64, f32), for first f32
    // we discard a0, now for f64 argument, which will go in F14F15, we must
    // first align GPR vector to even register by discarding a1, then discard
    // two GPRs a2 and a3. Now last f32 argument will go on stack.
    alignGPR(Source);
    discardNextGPRAndItsAliases(Source);
  }
  discardNextGPRAndItsAliases(Source);
  return true;
}

void TargetMIPS32::CallingConv::discardUnavailableVFPRegsAndTheirAliases(
    CfgVector<RegNumT> *Regs) {
  while (!Regs->empty() && VFPRegsUsed[Regs->back()]) {
    Regs->pop_back();
  }
}

void TargetMIPS32::lowerArguments() {
  VarList &Args = Func->getArgs();
  TargetMIPS32::CallingConv CC;

  // For each register argument, replace Arg in the argument list with the home
  // register. Then generate an instruction in the prolog to copy the home
  // register to the assigned location of Arg.
  Context.init(Func->getEntryNode());
  Context.setInsertPoint(Context.getCur());

  // v4f32 is returned through stack. $4 is setup by the caller and passed as
  // first argument implicitly. Callee then copies the return vector at $4.
  Variable *ImplicitRetVec = nullptr;
  if (isVectorFloatingType(Func->getReturnType())) {
    ImplicitRetVec = Func->makeVariable(IceType_i32);
    ImplicitRetVec->setName(Func, "ImplicitRet_v4f32");
    ImplicitRetVec->setIsArg();
    Args.insert(Args.begin(), ImplicitRetVec);
    setImplicitRet(ImplicitRetVec);
  }

  for (SizeT i = 0, E = Args.size(); i < E; ++i) {
    Variable *Arg = Args[i];
    Type Ty = Arg->getType();
    RegNumT RegNum;
    if (!CC.argInReg(Ty, i, &RegNum)) {
      continue;
    }
    Variable *RegisterArg = Func->makeVariable(Ty);
    if (BuildDefs::dump()) {
      RegisterArg->setName(Func, "home_reg:" + Arg->getName());
    }
    RegisterArg->setIsArg();
    Arg->setIsArg(false);
    Args[i] = RegisterArg;

    if (isVectorType(Ty)) {
      auto *RegisterArgVec = llvm::cast<VariableVecOn32>(RegisterArg);
      RegisterArgVec->initVecElement(Func);
      RegisterArgVec->getContainers()[0]->setRegNum(
          RegNumT::fixme((unsigned)RegNum + 0));
      RegisterArgVec->getContainers()[1]->setRegNum(
          RegNumT::fixme((unsigned)RegNum + 1));
      // First two elements of second vector argument are passed
      // in $6:$7 and remaining two on stack. Do not assign register
      // to this is second vector argument.
      if (i == 0) {
        RegisterArgVec->getContainers()[2]->setRegNum(
            RegNumT::fixme((unsigned)RegNum + 2));
        RegisterArgVec->getContainers()[3]->setRegNum(
            RegNumT::fixme((unsigned)RegNum + 3));
      } else {
        RegisterArgVec->getContainers()[2]->setRegNum(
            RegNumT::fixme(RegNumT()));
        RegisterArgVec->getContainers()[3]->setRegNum(
            RegNumT::fixme(RegNumT()));
      }
    } else {
      switch (Ty) {
      default: { RegisterArg->setRegNum(RegNum); } break;
      case IceType_i64: {
        auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg);
        RegisterArg64->initHiLo(Func);
        RegisterArg64->getLo()->setRegNum(
            RegNumT::fixme(RegMIPS32::get64PairFirstRegNum(RegNum)));
        RegisterArg64->getHi()->setRegNum(
            RegNumT::fixme(RegMIPS32::get64PairSecondRegNum(RegNum)));
      } break;
      }
    }
    Context.insert<InstAssign>(Arg, RegisterArg);
  }

  // Insert fake use of ImplicitRet_v4f32 to keep it live
  if (ImplicitRetVec) {
    for (CfgNode *Node : Func->getNodes()) {
      for (Inst &Instr : Node->getInsts()) {
        if (llvm::isa<InstRet>(&Instr)) {
          Context.setInsertPoint(Instr);
          Context.insert<InstFakeUse>(ImplicitRetVec);
          break;
        }
      }
    }
  }
}

Type TargetMIPS32::stackSlotType() { return IceType_i32; }

// Helper function for addProlog().
//
// This assumes Arg is an argument passed on the stack. This sets the frame
// offset for Arg and updates InArgsSizeBytes according to Arg's width. For an
// I64 arg that has been split into Lo and Hi components, it calls itself
// recursively on the components, taking care to handle Lo first because of the
// little-endian architecture. Lastly, this function generates an instruction
// to copy Arg into its assigned register if applicable.
void TargetMIPS32::finishArgumentLowering(Variable *Arg, bool PartialOnStack,
                                          Variable *FramePtr,
                                          size_t BasicFrameOffset,
                                          size_t *InArgsSizeBytes) {
  const Type Ty = Arg->getType();
  *InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);

  // If $4 is used for any scalar type (or returining v4f32) then the next
  // vector type if passed in $6:$7:stack:stack. Load 3nd and 4th element
  // from agument stack.
  if (auto *ArgVecOn32 = llvm::dyn_cast<VariableVecOn32>(Arg)) {
    if (PartialOnStack == false) {
      auto *Elem0 = ArgVecOn32->getContainers()[0];
      auto *Elem1 = ArgVecOn32->getContainers()[1];
      finishArgumentLowering(Elem0, PartialOnStack, FramePtr, BasicFrameOffset,
                             InArgsSizeBytes);
      finishArgumentLowering(Elem1, PartialOnStack, FramePtr, BasicFrameOffset,
                             InArgsSizeBytes);
    }
    auto *Elem2 = ArgVecOn32->getContainers()[2];
    auto *Elem3 = ArgVecOn32->getContainers()[3];
    finishArgumentLowering(Elem2, PartialOnStack, FramePtr, BasicFrameOffset,
                           InArgsSizeBytes);
    finishArgumentLowering(Elem3, PartialOnStack, FramePtr, BasicFrameOffset,
                           InArgsSizeBytes);
    return;
  }

  if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
    Variable *const Lo = Arg64On32->getLo();
    Variable *const Hi = Arg64On32->getHi();
    finishArgumentLowering(Lo, PartialOnStack, FramePtr, BasicFrameOffset,
                           InArgsSizeBytes);
    finishArgumentLowering(Hi, PartialOnStack, FramePtr, BasicFrameOffset,
                           InArgsSizeBytes);
    return;
  }

  assert(Ty != IceType_i64);
  assert(!isVectorType(Ty));

  const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes;
  *InArgsSizeBytes += typeWidthInBytesOnStack(Ty);

  if (!Arg->hasReg()) {
    Arg->setStackOffset(ArgStackOffset);
    return;
  }

  // If the argument variable has been assigned a register, we need to copy the
  // value from the stack slot.
  Variable *Parameter = Func->makeVariable(Ty);
  Parameter->setMustNotHaveReg();
  Parameter->setStackOffset(ArgStackOffset);
  _mov(Arg, Parameter);
}

void TargetMIPS32::addProlog(CfgNode *Node) {
  // Stack frame layout:
  //
  // +------------------------+
  // | 1. preserved registers |
  // +------------------------+
  // | 2. padding             |
  // +------------------------+
  // | 3. global spill area   |
  // +------------------------+
  // | 4. padding             |
  // +------------------------+
  // | 5. local spill area    |
  // +------------------------+
  // | 6. padding             |
  // +------------------------+
  // | 7. allocas             |
  // +------------------------+
  // | 8. padding             |
  // +------------------------+
  // | 9. out args           |
  // +------------------------+ <--- StackPointer
  //
  // The following variables record the size in bytes of the given areas:
  //  * PreservedRegsSizeBytes: area 1
  //  * SpillAreaPaddingBytes:  area 2
  //  * GlobalsSize:            area 3
  //  * GlobalsAndSubsequentPaddingSize: areas 3 - 4
  //  * LocalsSpillAreaSize:    area 5
  //  * SpillAreaSizeBytes:     areas 2 - 9
  //  * maxOutArgsSizeBytes():  area 9

  Context.init(Node);
  Context.setInsertPoint(Context.getCur());

  SmallBitVector CalleeSaves = getRegisterSet(RegSet_CalleeSave, RegSet_None);
  RegsUsed = SmallBitVector(CalleeSaves.size());

  VarList SortedSpilledVariables;

  size_t GlobalsSize = 0;
  // If there is a separate locals area, this represents that area. Otherwise
  // it counts any variable not counted by GlobalsSize.
  SpillAreaSizeBytes = 0;
  // If there is a separate locals area, this specifies the alignment for it.
  uint32_t LocalsSlotsAlignmentBytes = 0;
  // The entire spill locations area gets aligned to largest natural alignment
  // of the variables that have a spill slot.
  uint32_t SpillAreaAlignmentBytes = 0;
  // For now, we don't have target-specific variables that need special
  // treatment (no stack-slot-linked SpillVariable type).
  std::function<bool(Variable *)> TargetVarHook = [](Variable *Var) {
    static constexpr bool AssignStackSlot = false;
    static constexpr bool DontAssignStackSlot = !AssignStackSlot;
    if (llvm::isa<Variable64On32>(Var)) {
      return DontAssignStackSlot;
    }
    return AssignStackSlot;
  };

  // Compute the list of spilled variables and bounds for GlobalsSize, etc.
  getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize,
                        &SpillAreaSizeBytes, &SpillAreaAlignmentBytes,
                        &LocalsSlotsAlignmentBytes, TargetVarHook);
  uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes;
  SpillAreaSizeBytes += GlobalsSize;

  PreservedGPRs.reserve(CalleeSaves.size());

  // Consider FP and RA as callee-save / used as needed.
  if (UsesFramePointer) {
    if (RegsUsed[RegMIPS32::Reg_FP]) {
      llvm::report_fatal_error("Frame pointer has been used.");
    }
    CalleeSaves[RegMIPS32::Reg_FP] = true;
    RegsUsed[RegMIPS32::Reg_FP] = true;
  }
  if (!MaybeLeafFunc) {
    CalleeSaves[RegMIPS32::Reg_RA] = true;
    RegsUsed[RegMIPS32::Reg_RA] = true;
  }

  // Make two passes over the used registers. The first pass records all the
  // used registers -- and their aliases. Then, we figure out which GPR
  // registers should be saved.
  SmallBitVector ToPreserve(RegMIPS32::Reg_NUM);
  for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
    if (CalleeSaves[i] && RegsUsed[i]) {
      ToPreserve |= RegisterAliases[i];
    }
  }

  uint32_t NumCallee = 0;

  // RegClasses is a tuple of
  //
  // <First Register in Class, Last Register in Class, Vector of Save Registers>
  //
  // We use this tuple to figure out which register we should save/restore
  // during
  // prolog/epilog.
  using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>;
  const RegClassType RegClass = RegClassType(
      RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_GPR_Last, &PreservedGPRs);
  const uint32_t FirstRegInClass = std::get<0>(RegClass);
  const uint32_t LastRegInClass = std::get<1>(RegClass);
  VarList *const PreservedRegsInClass = std::get<2>(RegClass);
  for (uint32_t Reg = LastRegInClass; Reg > FirstRegInClass; Reg--) {
    if (!ToPreserve[Reg]) {
      continue;
    }
    ++NumCallee;
    Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg));
    PreservedRegsSizeBytes +=
        typeWidthInBytesOnStack(PhysicalRegister->getType());
    PreservedRegsInClass->push_back(PhysicalRegister);
  }

  Ctx->statsUpdateRegistersSaved(NumCallee);

  // Align the variables area. SpillAreaPaddingBytes is the size of the region
  // after the preserved registers and before the spill areas.
  // LocalsSlotsPaddingBytes is the amount of padding between the globals and
  // locals area if they are separate.
  assert(SpillAreaAlignmentBytes <= MIPS32_STACK_ALIGNMENT_BYTES);
  (void)MIPS32_STACK_ALIGNMENT_BYTES;
  assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes);
  uint32_t SpillAreaPaddingBytes = 0;
  uint32_t LocalsSlotsPaddingBytes = 0;
  alignStackSpillAreas(PreservedRegsSizeBytes, SpillAreaAlignmentBytes,
                       GlobalsSize, LocalsSlotsAlignmentBytes,
                       &SpillAreaPaddingBytes, &LocalsSlotsPaddingBytes);
  SpillAreaSizeBytes += SpillAreaPaddingBytes + LocalsSlotsPaddingBytes;
  uint32_t GlobalsAndSubsequentPaddingSize =
      GlobalsSize + LocalsSlotsPaddingBytes;

  // Adds the out args space to the stack, and align SP if necessary.
  if (!NeedsStackAlignment) {
    SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1);
  } else {
    SpillAreaSizeBytes = applyStackAlignment(
        SpillAreaSizeBytes +
        (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes));
  }

  // Combine fixed alloca with SpillAreaSize.
  SpillAreaSizeBytes += FixedAllocaSizeBytes;

  TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes;

  // Generate "addiu sp, sp, -TotalStackSizeBytes"
  if (TotalStackSizeBytes) {
    // Use the scratch register if needed to legalize the immediate.
    Sandboxer(this).addiu_sp(-TotalStackSizeBytes);
  }

  Ctx->statsUpdateFrameBytes(TotalStackSizeBytes);

  if (!PreservedGPRs.empty()) {
    uint32_t StackOffset = TotalStackSizeBytes;
    for (Variable *Var : *PreservedRegsInClass) {
      Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum());
      StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType());
      Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
      OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
          Func, IceType_i32, SP,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
      Sandboxer(this).sw(PhysicalRegister, MemoryLocation);
    }
  }

  Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP);

  // Generate "mov FP, SP" if needed.
  if (UsesFramePointer) {
    Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
    _mov(FP, SP);
    // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode).
    Context.insert<InstFakeUse>(FP);
  }

  // Fill in stack offsets for stack args, and copy args into registers for
  // those that were register-allocated. Args are pushed right to left, so
  // Arg[0] is closest to the stack/frame pointer.
  const VarList &Args = Func->getArgs();
  size_t InArgsSizeBytes = MIPS32_MAX_GPR_ARG * 4;
  TargetMIPS32::CallingConv CC;
  uint32_t ArgNo = 0;

  for (Variable *Arg : Args) {
    RegNumT DummyReg;
    const Type Ty = Arg->getType();
    bool PartialOnStack;
    // Skip arguments passed in registers.
    if (CC.argInReg(Ty, ArgNo, &DummyReg)) {
      // Load argument from stack:
      // 1. If this is first vector argument and return type is v4f32.
      //    In this case $4 is used to pass stack address implicitly.
      //    3rd and 4th element of vector argument is passed through stack.
      // 2. If this is second vector argument.
      if (ArgNo != 0 && isVectorType(Ty)) {
        PartialOnStack = true;
        finishArgumentLowering(Arg, PartialOnStack, FP, TotalStackSizeBytes,
                               &InArgsSizeBytes);
      }
    } else {
      PartialOnStack = false;
      finishArgumentLowering(Arg, PartialOnStack, FP, TotalStackSizeBytes,
                             &InArgsSizeBytes);
    }
    ++ArgNo;
  }

  // Fill in stack offsets for locals.
  assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes,
                      SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize);
  this->HasComputedFrame = true;

  if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) {
    OstreamLocker _(Func->getContext());
    Ostream &Str = Func->getContext()->getStrDump();

    Str << "Stack layout:\n";
    uint32_t SPAdjustmentPaddingSize =
        SpillAreaSizeBytes - LocalsSpillAreaSize -
        GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes -
        MaxOutArgsSizeBytes;
    Str << " in-args = " << InArgsSizeBytes << " bytes\n"
        << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n"
        << " spill area padding = " << SpillAreaPaddingBytes << " bytes\n"
        << " globals spill area = " << GlobalsSize << " bytes\n"
        << " globals-locals spill areas intermediate padding = "
        << GlobalsAndSubsequentPaddingSize - GlobalsSize << " bytes\n"
        << " locals spill area = " << LocalsSpillAreaSize << " bytes\n"
        << " SP alignment padding = " << SPAdjustmentPaddingSize << " bytes\n";

    Str << "Stack details:\n"
        << " SP adjustment = " << SpillAreaSizeBytes << " bytes\n"
        << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n"
        << " outgoing args size = " << MaxOutArgsSizeBytes << " bytes\n"
        << " locals spill area alignment = " << LocalsSlotsAlignmentBytes
        << " bytes\n"
        << " is FP based = " << 1 << "\n";
  }
  return;
}

void TargetMIPS32::addEpilog(CfgNode *Node) {
  InstList &Insts = Node->getInsts();
  InstList::reverse_iterator RI, E;
  for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) {
    if (llvm::isa<InstMIPS32Ret>(*RI))
      break;
  }
  if (RI == E)
    return;

  // Convert the reverse_iterator position into its corresponding (forward)
  // iterator position.
  InstList::iterator InsertPoint = reverseToForwardIterator(RI);
  --InsertPoint;
  Context.init(Node);
  Context.setInsertPoint(InsertPoint);

  Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
  if (UsesFramePointer) {
    Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP);
    // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
    // use of SP before the assignment of SP=FP keeps previous SP adjustments
    // from being dead-code eliminated.
    Context.insert<InstFakeUse>(SP);
    Sandboxer(this).reset_sp(FP);
  }

  VarList::reverse_iterator RIter, END;

  if (!PreservedGPRs.empty()) {
    uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes;
    for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend();
         RIter != END; ++RIter) {
      Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum());
      Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
      OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
          Func, IceType_i32, SP,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
      _lw(PhysicalRegister, MemoryLocation);
      StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType());
    }
  }

  if (TotalStackSizeBytes) {
    Sandboxer(this).addiu_sp(TotalStackSizeBytes);
  }
  if (!getFlags().getUseSandboxing())
    return;

  Variable *RA = getPhysicalRegister(RegMIPS32::Reg_RA);
  Variable *RetValue = nullptr;
  if (RI->getSrcSize())
    RetValue = llvm::cast<Variable>(RI->getSrc(0));

  Sandboxer(this).ret(RA, RetValue);

  RI->setDeleted();
}

Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister(
    Variable *Base, int32_t Offset, RegNumT ScratchRegNum) {
  // Legalize will likely need a lui/ori combination, but if the top bits are
  // all 0 from negating the offset and subtracting, we could use that instead.
  const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0;
  Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum);
  if (ShouldSub) {
    Target->_addi(ScratchReg, Base, -Offset);
  } else {
    constexpr bool SignExt = true;
    if (!OperandMIPS32Mem::canHoldOffset(Base->getType(), SignExt, Offset)) {
      const uint32_t UpperBits = (Offset >> 16) & 0xFFFF;
      const uint32_t LowerBits = Offset & 0xFFFF;
      Target->_lui(ScratchReg, Target->Ctx->getConstantInt32(UpperBits));
      if (LowerBits)
        Target->_ori(ScratchReg, ScratchReg, LowerBits);
      Target->_addu(ScratchReg, ScratchReg, Base);
    } else {
      Target->_addiu(ScratchReg, Base, Offset);
    }
  }

  return ScratchReg;
}

void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
  Variable *Dest = MovInstr->getDest();
  assert(Dest != nullptr);
  const Type DestTy = Dest->getType();
  assert(DestTy != IceType_i64);

  Operand *Src = MovInstr->getSrc(0);
  const Type SrcTy = Src->getType();
  (void)SrcTy;
  assert(SrcTy != IceType_i64);

  bool Legalized = false;
  auto *SrcR = llvm::cast<Variable>(Src);
  if (Dest->hasReg() && SrcR->hasReg()) {
    // This might be a GP to/from FP move generated due to argument passing.
    // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of
    // different types.
    const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum());
    const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum());
    const RegNumT SRegNum = SrcR->getRegNum();
    const RegNumT DRegNum = Dest->getRegNum();
    if (IsDstGPR != IsSrcGPR) {
      if (IsDstGPR) {
        // Dest is GPR and SrcR is FPR. Use mfc1.
        int32_t TypeWidth = typeWidthInBytes(DestTy);
        if (MovInstr->getDestHi() != nullptr)
          TypeWidth += typeWidthInBytes(MovInstr->getDestHi()->getType());
        if (TypeWidth == 8) {
          // Split it into two mfc1 instructions
          Variable *SrcGPRHi = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum));
          Variable *SrcGPRLo = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum));
          Variable *DstFPRHi, *DstFPRLo;
          if (MovInstr->getDestHi() != nullptr && Dest != nullptr) {
            DstFPRHi = Target->makeReg(IceType_i32,
                                       MovInstr->getDestHi()->getRegNum());
            DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum());
          } else {
            DstFPRHi = Target->makeReg(
                IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum));
            DstFPRLo = Target->makeReg(
                IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum));
          }
          Target->_mov(DstFPRHi, SrcGPRLo);
          Target->_mov(DstFPRLo, SrcGPRHi);
          Legalized = true;
        } else {
          Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum);
          Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum);
          Target->_mov(DstFPR, SrcGPR);
          Legalized = true;
        }
      } else {
        // Dest is FPR and SrcR is GPR. Use mtc1.
        if (typeWidthInBytes(Dest->getType()) == 8) {
          Variable *SrcGPRHi, *SrcGPRLo;
          // SrcR could be $zero which is i32
          if (SRegNum == RegMIPS32::Reg_ZERO) {
            SrcGPRHi = Target->makeReg(IceType_i32, SRegNum);
            SrcGPRLo = SrcGPRHi;
          } else {
            // Split it into two mtc1 instructions
            if (MovInstr->getSrcSize() == 2) {
              const auto FirstReg =
                  (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum();
              const auto SecondReg =
                  (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum();
              SrcGPRHi = Target->makeReg(IceType_i32, FirstReg);
              SrcGPRLo = Target->makeReg(IceType_i32, SecondReg);
            } else {
              SrcGPRLo = Target->makeReg(
                  IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum));
              SrcGPRHi = Target->makeReg(
                  IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum));
            }
          }
          Variable *DstFPRHi = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum));
          Variable *DstFPRLo = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum));
          Target->_mov(DstFPRHi, SrcGPRLo);
          Target->_mov(DstFPRLo, SrcGPRHi);
          Legalized = true;
        } else {
          Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum);
          Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum);
          Target->_mov(DstFPR, SrcGPR);
          Legalized = true;
        }
      }
    }
    if (Legalized) {
      if (MovInstr->isDestRedefined()) {
        Target->_set_dest_redefined();
      }
      MovInstr->setDeleted();
      return;
    }
  }

  if (!Dest->hasReg()) {
    auto *SrcR = llvm::cast<Variable>(Src);
    assert(SrcR->hasReg());
    assert(!SrcR->isRematerializable());
    int32_t Offset = Dest->getStackOffset();

    // This is a _mov(Mem(), Variable), i.e., a store.
    auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());

    OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
        Target->Func, DestTy, Base,
        llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
    OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create(
        Target->Func, DestTy, Base,
        llvm::cast<ConstantInteger32>(
            Target->Ctx->getConstantInt32(Offset + 4)));
    OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);

    // FP arguments are passed in GP reg if first argument is in GP. In this
    // case type of the SrcR is still FP thus we need to explicitly generate sw
    // instead of swc1.
    const RegNumT RegNum = SrcR->getRegNum();
    const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum());
    if (SrcTy == IceType_f32 && IsSrcGPReg) {
      Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum);
      Sandboxer(Target).sw(SrcGPR, Addr);
    } else if (SrcTy == IceType_f64 && IsSrcGPReg) {
      Variable *SrcGPRHi =
          Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum));
      Variable *SrcGPRLo = Target->makeReg(
          IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum));
      Sandboxer(Target).sw(SrcGPRHi, Addr);
      OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
      Sandboxer(Target).sw(SrcGPRLo, AddrHi);
    } else if (DestTy == IceType_f64 && IsSrcGPReg) {
      const auto FirstReg =
          (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum();
      const auto SecondReg =
          (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum();
      Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg);
      Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg);
      Sandboxer(Target).sw(SrcGPRLo, Addr);
      OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
      Sandboxer(Target).sw(SrcGPRHi, AddrHi);
    } else {
      Sandboxer(Target).sw(SrcR, Addr);
    }

    Target->Context.insert<InstFakeDef>(Dest);
    Legalized = true;
  } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
    if (Var->isRematerializable()) {
      // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).

      // ExtraOffset is only needed for stack-pointer based frames as we have
      // to account for spill storage.
      const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg())
                                      ? Target->getFrameFixedAllocaOffset()
                                      : 0;

      const int32_t Offset = Var->getStackOffset() + ExtraOffset;
      Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
      Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
      Target->_mov(Dest, T);
      Legalized = true;
    } else {
      if (!Var->hasReg()) {
        // This is a _mov(Variable, Mem()), i.e., a load.
        const int32_t Offset = Var->getStackOffset();
        auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
        const RegNumT RegNum = Dest->getRegNum();
        const bool IsDstGPReg = RegMIPS32::isGPRReg(Dest->getRegNum());
        // If we are moving i64 to a double using stack then the address may
        // not be aligned to 8-byte boundary as we split i64 into Hi-Lo parts
        // and store them individually with 4-byte alignment. Load the Hi-Lo
        // parts in TmpReg and move them to the dest using mtc1.
        if (DestTy == IceType_f64 && !Utils::IsAligned(Offset, 8) &&
            !IsDstGPReg) {
          auto *Reg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
          const RegNumT RegNum = Dest->getRegNum();
          Variable *DestLo = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairFirstRegNum(RegNum));
          Variable *DestHi = Target->makeReg(
              IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum));
          OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create(
              Target->Func, IceType_i32, Base,
              llvm::cast<ConstantInteger32>(
                  Target->Ctx->getConstantInt32(Offset)));
          OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create(
              Target->Func, IceType_i32, Base,
              llvm::cast<ConstantInteger32>(
                  Target->Ctx->getConstantInt32(Offset + 4)));
          Sandboxer(Target).lw(Reg, AddrLo);
          Target->_mov(DestLo, Reg);
          Sandboxer(Target).lw(Reg, AddrHi);
          Target->_mov(DestHi, Reg);
        } else {
          OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
              Target->Func, DestTy, Base,
              llvm::cast<ConstantInteger32>(
                  Target->Ctx->getConstantInt32(Offset)));
          OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);
          OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create(
              Target->Func, DestTy, Base,
              llvm::cast<ConstantInteger32>(
                  Target->Ctx->getConstantInt32(Offset + 4)));
          // FP arguments are passed in GP reg if first argument is in GP.
          // In this case type of the Dest is still FP thus we need to
          // explicitly generate lw instead of lwc1.
          if (DestTy == IceType_f32 && IsDstGPReg) {
            Variable *DstGPR = Target->makeReg(IceType_i32, RegNum);
            Sandboxer(Target).lw(DstGPR, Addr);
          } else if (DestTy == IceType_f64 && IsDstGPReg) {
            Variable *DstGPRHi = Target->makeReg(
                IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum));
            Variable *DstGPRLo = Target->makeReg(
                IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum));
            Sandboxer(Target).lw(DstGPRHi, Addr);
            OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
            Sandboxer(Target).lw(DstGPRLo, AddrHi);
          } else if (DestTy == IceType_f64 && IsDstGPReg) {
            const auto FirstReg =
                (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum();
            const auto SecondReg =
                (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum();
            Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg);
            Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg);
            Sandboxer(Target).lw(DstGPRLo, Addr);
            OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
            Sandboxer(Target).lw(DstGPRHi, AddrHi);
          } else {
            Sandboxer(Target).lw(Dest, Addr);
          }
        }
        Legalized = true;
      }
    }
  }

  if (Legalized) {
    if (MovInstr->isDestRedefined()) {
      Target->_set_dest_redefined();
    }
    MovInstr->setDeleted();
  }
}

OperandMIPS32Mem *
TargetMIPS32::PostLoweringLegalizer::legalizeMemOperand(OperandMIPS32Mem *Mem) {
  if (llvm::isa<ConstantRelocatable>(Mem->getOffset())) {
    return nullptr;
  }
  Variable *Base = Mem->getBase();
  auto *Ci32 = llvm::cast<ConstantInteger32>(Mem->getOffset());
  int32_t Offset = Ci32->getValue();

  if (Base->isRematerializable()) {
    const int32_t ExtraOffset =
        (Base->getRegNum() == Target->getFrameOrStackReg())
            ? Target->getFrameFixedAllocaOffset()
            : 0;
    Offset += Base->getStackOffset() + ExtraOffset;
    Base = Target->getPhysicalRegister(Base->getRegNum());
  }

  constexpr bool SignExt = true;
  if (!OperandMIPS32Mem::canHoldOffset(Mem->getType(), SignExt, Offset)) {
    Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg());
    Offset = 0;
  }

  return OperandMIPS32Mem::create(
      Target->Func, Mem->getType(), Base,
      llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
}

Variable *TargetMIPS32::PostLoweringLegalizer::legalizeImmediate(int32_t Imm) {
  Variable *Reg = nullptr;
  if (!((std::numeric_limits<int16_t>::min() <= Imm) &&
        (Imm <= std::numeric_limits<int16_t>::max()))) {
    const uint32_t UpperBits = (Imm >> 16) & 0xFFFF;
    const uint32_t LowerBits = Imm & 0xFFFF;
    Variable *TReg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
    Reg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
    if (LowerBits) {
      Target->_lui(TReg, Target->Ctx->getConstantInt32(UpperBits));
      Target->_ori(Reg, TReg, LowerBits);
    } else {
      Target->_lui(Reg, Target->Ctx->getConstantInt32(UpperBits));
    }
  }
  return Reg;
}

void TargetMIPS32::postLowerLegalization() {
  Func->dump("Before postLowerLegalization");
  assert(hasComputedFrame());
  for (CfgNode *Node : Func->getNodes()) {
    Context.init(Node);
    PostLoweringLegalizer Legalizer(this);
    while (!Context.atEnd()) {
      PostIncrLoweringContext PostIncrement(Context);
      Inst *CurInstr = iteratorToInst(Context.getCur());
      const SizeT NumSrcs = CurInstr->getSrcSize();
      Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0);
      Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1);
      auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0);
      auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0);
      auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1);
      Variable *Dst = CurInstr->getDest();
      if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) {
        Legalizer.legalizeMov(MovInstr);
        continue;
      }
      if (llvm::isa<InstMIPS32Sw>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
          Sandboxer(this).sw(Src0V, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (llvm::isa<InstMIPS32Swc1>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
          _swc1(Src0V, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
          _sdc1(Src0V, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (llvm::isa<InstMIPS32Lw>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
          Sandboxer(this).lw(Dst, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
          _lwc1(Dst, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (llvm::isa<InstMIPS32Ldc1>(CurInstr)) {
        if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
          _ldc1(Dst, LegalMem);
          CurInstr->setDeleted();
        }
        continue;
      }
      if (auto *AddiuInstr = llvm::dyn_cast<InstMIPS32Addiu>(CurInstr)) {
        if (auto *LegalImm = Legalizer.legalizeImmediate(
                static_cast<int32_t>(AddiuInstr->getImmediateValue()))) {
          _addu(Dst, Src0V, LegalImm);
          CurInstr->setDeleted();
        }
        continue;
      }
    }
  }
}

Operand *TargetMIPS32::loOperand(Operand *Operand) {
  assert(Operand->getType() == IceType_i64);
  if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
    return Var64On32->getLo();
  if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
    return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue()));
  }
  if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
    // Conservatively disallow memory operands with side-effects (pre/post
    // increment) in case of duplication.
    assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
    return OperandMIPS32Mem::create(Func, IceType_i32, Mem->getBase(),
                                    Mem->getOffset(), Mem->getAddrMode());
  }
  llvm_unreachable("Unsupported operand type");
  return nullptr;
}

Operand *TargetMIPS32::getOperandAtIndex(Operand *Operand, Type BaseType,
                                         uint32_t Index) {
  if (!isVectorType(Operand->getType())) {
    llvm::report_fatal_error("getOperandAtIndex: Operand is not vector");
    return nullptr;
  }

  if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
    assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
    Variable *Base = Mem->getBase();
    auto *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
    assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4));
    int32_t NextOffsetVal =
        Offset->getValue() + (Index * typeWidthInBytes(BaseType));
    constexpr bool NoSignExt = false;
    if (!OperandMIPS32Mem::canHoldOffset(BaseType, NoSignExt, NextOffsetVal)) {
      Constant *_4 = Ctx->getConstantInt32(4);
      Variable *NewBase = Func->makeVariable(Base->getType());
      lowerArithmetic(
          InstArithmetic::create(Func, InstArithmetic::Add, NewBase, Base, _4));
      Base = NewBase;
    } else {
      Offset =
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(NextOffsetVal));
    }
    return OperandMIPS32Mem::create(Func, BaseType, Base, Offset,
                                    Mem->getAddrMode());
  }

  if (auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(Operand))
    return VarVecOn32->getContainers()[Index];

  llvm_unreachable("Unsupported operand type");
  return nullptr;
}

Operand *TargetMIPS32::hiOperand(Operand *Operand) {
  assert(Operand->getType() == IceType_i64);
  if (Operand->getType() != IceType_i64)
    return Operand;
  if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
    return Var64On32->getHi();
  if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
    return Ctx->getConstantInt32(
        static_cast<uint32_t>(Const->getValue() >> 32));
  }
  if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
    // Conservatively disallow memory operands with side-effects
    // in case of duplication.
    assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset);
    const Type SplitType = IceType_i32;
    Variable *Base = Mem->getBase();
    auto *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
    assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4));
    int32_t NextOffsetVal = Offset->getValue() + 4;
    constexpr bool SignExt = false;
    if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) {
      // We have to make a temp variable and add 4 to either Base or Offset.
      // If we add 4 to Offset, this will convert a non-RegReg addressing
      // mode into a RegReg addressing mode. Since NaCl sandboxing disallows
      // RegReg addressing modes, prefer adding to base and replacing instead.
      // Thus we leave the old offset alone.
      Constant *Four = Ctx->getConstantInt32(4);
      Variable *NewBase = Func->makeVariable(Base->getType());
      lowerArithmetic(InstArithmetic::create(Func, InstArithmetic::Add, NewBase,
                                             Base, Four));
      Base = NewBase;
    } else {
      Offset =
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(NextOffsetVal));
    }
    return OperandMIPS32Mem::create(Func, SplitType, Base, Offset,
                                    Mem->getAddrMode());
  }
  llvm_unreachable("Unsupported operand type");
  return nullptr;
}

SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include,
                                            RegSetMask Exclude) const {
  SmallBitVector Registers(RegMIPS32::Reg_NUM);

#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt,    \
          isI64Pair, isFP32, isFP64, isVec128, alias_init)                     \
  if (scratch && (Include & RegSet_CallerSave))                                \
    Registers[RegMIPS32::val] = true;                                          \
  if (preserved && (Include & RegSet_CalleeSave))                              \
    Registers[RegMIPS32::val] = true;                                          \
  if (stackptr && (Include & RegSet_StackPointer))                             \
    Registers[RegMIPS32::val] = true;                                          \
  if (frameptr && (Include & RegSet_FramePointer))                             \
    Registers[RegMIPS32::val] = true;                                          \
  if (scratch && (Exclude & RegSet_CallerSave))                                \
    Registers[RegMIPS32::val] = false;                                         \
  if (preserved && (Exclude & RegSet_CalleeSave))                              \
    Registers[RegMIPS32::val] = false;                                         \
  if (stackptr && (Exclude & RegSet_StackPointer))                             \
    Registers[RegMIPS32::val] = false;                                         \
  if (frameptr && (Exclude & RegSet_FramePointer))                             \
    Registers[RegMIPS32::val] = false;

  REGMIPS32_TABLE

#undef X

  if (NeedSandboxing) {
    Registers[RegMIPS32::Reg_T6] = false;
    Registers[RegMIPS32::Reg_T7] = false;
    Registers[RegMIPS32::Reg_T8] = false;
  }
  return Registers;
}

void TargetMIPS32::lowerAlloca(const InstAlloca *Instr) {
  // Conservatively require the stack to be aligned. Some stack adjustment
  // operations implemented below assume that the stack is aligned before the
  // alloca. All the alloca code ensures that the stack alignment is preserved
  // after the alloca. The stack alignment restriction can be relaxed in some
  // cases.
  NeedsStackAlignment = true;

  // For default align=0, set it to the real value 1, to avoid any
  // bit-manipulation problems below.
  const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes());

  // LLVM enforces power of 2 alignment.
  assert(llvm::isPowerOf2_32(AlignmentParam));
  assert(llvm::isPowerOf2_32(MIPS32_STACK_ALIGNMENT_BYTES));

  const uint32_t Alignment =
      std::max(AlignmentParam, MIPS32_STACK_ALIGNMENT_BYTES);
  const bool OverAligned = Alignment > MIPS32_STACK_ALIGNMENT_BYTES;
  const bool OptM1 = Func->getOptLevel() == Opt_m1;
  const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset();
  const bool UseFramePointer =
      hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1;

  if (UseFramePointer)
    setHasFramePointer();

  Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);

  Variable *Dest = Instr->getDest();
  Operand *TotalSize = Instr->getSizeInBytes();

  if (const auto *ConstantTotalSize =
          llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
    const uint32_t Value =
        Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment);
    FixedAllocaSizeBytes += Value;
    // Constant size alloca.
    if (!UseFramePointer) {
      // If we don't need a Frame Pointer, this alloca has a known offset to the
      // stack pointer. We don't need adjust the stack pointer, nor assign any
      // value to Dest, as Dest is rematerializable.
      assert(Dest->isRematerializable());
      Context.insert<InstFakeDef>(Dest);
      return;
    }

    if (Alignment > MIPS32_STACK_ALIGNMENT_BYTES) {
      CurrentAllocaOffset =
          Utils::applyAlignment(CurrentAllocaOffset, Alignment);
    }
    auto *T = I32Reg();
    _addiu(T, SP, CurrentAllocaOffset);
    _mov(Dest, T);
    CurrentAllocaOffset += Value;
    return;

  } else {
    // Non-constant sizes need to be adjusted to the next highest multiple of
    // the required alignment at runtime.
    VariableAllocaUsed = true;
    VariableAllocaAlignBytes = AlignmentParam;
    Variable *AlignAmount;
    auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg);
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    _addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1);
    _addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES);
    _and(T3, T1, T2);
    _subu(T4, SP, T3);
    if (Instr->getAlignInBytes()) {
      AlignAmount =
          legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg);
      _and(T5, T4, AlignAmount);
      _mov(Dest, T5);
    } else {
      _mov(Dest, T4);
    }
    if (OptM1)
      _mov(SP, Dest);
    else
      Sandboxer(this).reset_sp(Dest);
    return;
  }
}

void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
                                        Variable *Dest, Operand *Src0,
                                        Operand *Src1) {
  InstArithmetic::OpKind Op = Instr->getOp();
  auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
  auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
  Variable *Src0LoR = nullptr;
  Variable *Src1LoR = nullptr;
  Variable *Src0HiR = nullptr;
  Variable *Src1HiR = nullptr;

  switch (Op) {
  case InstArithmetic::_num:
    llvm::report_fatal_error("Unknown arithmetic operator");
    return;
  case InstArithmetic::Add: {
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Carry = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
         *T_Hi2 = I32Reg();
    _addu(T_Lo, Src0LoR, Src1LoR);
    _mov(DestLo, T_Lo);
    _sltu(T_Carry, T_Lo, Src0LoR);
    _addu(T_Hi, T_Carry, Src0HiR);
    _addu(T_Hi2, Src1HiR, T_Hi);
    _mov(DestHi, T_Hi2);
    return;
  }
  case InstArithmetic::And: {
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
    _and(T_Lo, Src0LoR, Src1LoR);
    _mov(DestLo, T_Lo);
    _and(T_Hi, Src0HiR, Src1HiR);
    _mov(DestHi, T_Hi);
    return;
  }
  case InstArithmetic::Sub: {
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Borrow = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
         *T_Hi2 = I32Reg();
    _subu(T_Lo, Src0LoR, Src1LoR);
    _mov(DestLo, T_Lo);
    _sltu(T_Borrow, Src0LoR, Src1LoR);
    _addu(T_Hi, T_Borrow, Src1HiR);
    _subu(T_Hi2, Src0HiR, T_Hi);
    _mov(DestHi, T_Hi2);
    return;
  }
  case InstArithmetic::Or: {
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
    _or(T_Lo, Src0LoR, Src1LoR);
    _mov(DestLo, T_Lo);
    _or(T_Hi, Src0HiR, Src1HiR);
    _mov(DestHi, T_Hi);
    return;
  }
  case InstArithmetic::Xor: {
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
    _xor(T_Lo, Src0LoR, Src1LoR);
    _mov(DestLo, T_Lo);
    _xor(T_Hi, Src0HiR, Src1HiR);
    _mov(DestHi, T_Hi);
    return;
  }
  case InstArithmetic::Mul: {
    // TODO(rkotler): Make sure that mul has the side effect of clobbering
    // LO, HI. Check for any other LO, HI quirkiness in this section.
    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));
    Src1HiR = legalizeToReg(hiOperand(Src1));
    auto *T_Lo = I32Reg(RegMIPS32::Reg_LO), *T_Hi = I32Reg(RegMIPS32::Reg_HI);
    auto *T1 = I32Reg(), *T2 = I32Reg();
    auto *TM1 = I32Reg(), *TM2 = I32Reg(), *TM3 = I32Reg(), *TM4 = I32Reg();
    _multu(T_Lo, Src0LoR, Src1LoR);
    Context.insert<InstFakeDef>(T_Hi, T_Lo);
    _mflo(T1, T_Lo);
    _mfhi(T2, T_Hi);
    _mov(DestLo, T1);
    _mul(TM1, Src0HiR, Src1LoR);
    _mul(TM2, Src0LoR, Src1HiR);
    _addu(TM3, TM1, T2);
    _addu(TM4, TM3, TM2);
    _mov(DestHi, TM4);
    return;
  }
  case InstArithmetic::Shl: {
    auto *T_Lo = I32Reg();
    auto *T_Hi = I32Reg();
    auto *T1_Lo = I32Reg();
    auto *T1_Hi = I32Reg();
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();

    if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
      Src0LoR = legalizeToReg(loOperand(Src0));
      int64_t ShiftAmount = Const->getValue();
      if (ShiftAmount == 1) {
        Src0HiR = legalizeToReg(hiOperand(Src0));
        _addu(T_Lo, Src0LoR, Src0LoR);
        _sltu(T1, T_Lo, Src0LoR);
        _addu(T2, T1, Src0HiR);
        _addu(T_Hi, Src0HiR, T2);
      } else if (ShiftAmount < INT32_BITS) {
        Src0HiR = legalizeToReg(hiOperand(Src0));
        _srl(T1, Src0LoR, INT32_BITS - ShiftAmount);
        _sll(T2, Src0HiR, ShiftAmount);
        _or(T_Hi, T1, T2);
        _sll(T_Lo, Src0LoR, ShiftAmount);
      } else if (ShiftAmount == INT32_BITS) {
        _addiu(T_Lo, getZero(), 0);
        _mov(T_Hi, Src0LoR);
      } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
        _sll(T_Hi, Src0LoR, ShiftAmount - INT32_BITS);
        _addiu(T_Lo, getZero(), 0);
      }
      _mov(DestLo, T_Lo);
      _mov(DestHi, T_Hi);
      return;
    }

    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));

    _sllv(T1, Src0HiR, Src1LoR);
    _not(T2, Src1LoR);
    _srl(T3, Src0LoR, 1);
    _srlv(T4, T3, T2);
    _or(T_Hi, T1, T4);
    _sllv(T_Lo, Src0LoR, Src1LoR);

    _mov(T1_Hi, T_Hi);
    _mov(T1_Lo, T_Lo);
    _andi(T5, Src1LoR, INT32_BITS);
    _movn(T1_Hi, T_Lo, T5);
    _movn(T1_Lo, getZero(), T5);
    _mov(DestHi, T1_Hi);
    _mov(DestLo, T1_Lo);
    return;
  }
  case InstArithmetic::Lshr: {

    auto *T_Lo = I32Reg();
    auto *T_Hi = I32Reg();
    auto *T1_Lo = I32Reg();
    auto *T1_Hi = I32Reg();
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();

    if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
      Src0HiR = legalizeToReg(hiOperand(Src0));
      int64_t ShiftAmount = Const->getValue();
      if (ShiftAmount < INT32_BITS) {
        Src0LoR = legalizeToReg(loOperand(Src0));
        _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
        _srl(T2, Src0LoR, ShiftAmount);
        _or(T_Lo, T1, T2);
        _srl(T_Hi, Src0HiR, ShiftAmount);
      } else if (ShiftAmount == INT32_BITS) {
        _mov(T_Lo, Src0HiR);
        _addiu(T_Hi, getZero(), 0);
      } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
        _srl(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
        _addiu(T_Hi, getZero(), 0);
      }
      _mov(DestLo, T_Lo);
      _mov(DestHi, T_Hi);
      return;
    }

    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));

    _srlv(T1, Src0LoR, Src1LoR);
    _not(T2, Src1LoR);
    _sll(T3, Src0HiR, 1);
    _sllv(T4, T3, T2);
    _or(T_Lo, T1, T4);
    _srlv(T_Hi, Src0HiR, Src1LoR);

    _mov(T1_Hi, T_Hi);
    _mov(T1_Lo, T_Lo);
    _andi(T5, Src1LoR, INT32_BITS);
    _movn(T1_Lo, T_Hi, T5);
    _movn(T1_Hi, getZero(), T5);
    _mov(DestHi, T1_Hi);
    _mov(DestLo, T1_Lo);
    return;
  }
  case InstArithmetic::Ashr: {

    auto *T_Lo = I32Reg();
    auto *T_Hi = I32Reg();
    auto *T1_Lo = I32Reg();
    auto *T1_Hi = I32Reg();
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    auto *T6 = I32Reg();

    if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
      Src0HiR = legalizeToReg(hiOperand(Src0));
      int64_t ShiftAmount = Const->getValue();
      if (ShiftAmount < INT32_BITS) {
        Src0LoR = legalizeToReg(loOperand(Src0));
        _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
        _srl(T2, Src0LoR, ShiftAmount);
        _or(T_Lo, T1, T2);
        _sra(T_Hi, Src0HiR, ShiftAmount);
      } else if (ShiftAmount == INT32_BITS) {
        _sra(T_Hi, Src0HiR, INT32_BITS - 1);
        _mov(T_Lo, Src0HiR);
      } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
        _sra(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
        _sra(T_Hi, Src0HiR, INT32_BITS - 1);
      }
      _mov(DestLo, T_Lo);
      _mov(DestHi, T_Hi);
      return;
    }

    Src0LoR = legalizeToReg(loOperand(Src0));
    Src1LoR = legalizeToReg(loOperand(Src1));
    Src0HiR = legalizeToReg(hiOperand(Src0));

    _srlv(T1, Src0LoR, Src1LoR);
    _not(T2, Src1LoR);
    _sll(T3, Src0HiR, 1);
    _sllv(T4, T3, T2);
    _or(T_Lo, T1, T4);
    _srav(T_Hi, Src0HiR, Src1LoR);

    _mov(T1_Hi, T_Hi);
    _mov(T1_Lo, T_Lo);
    _andi(T5, Src1LoR, INT32_BITS);
    _movn(T1_Lo, T_Hi, T5);
    _sra(T6, Src0HiR, INT32_BITS - 1);
    _movn(T1_Hi, T6, T5);
    _mov(DestHi, T1_Hi);
    _mov(DestLo, T1_Lo);
    return;
  }
  case InstArithmetic::Fadd:
  case InstArithmetic::Fsub:
  case InstArithmetic::Fmul:
  case InstArithmetic::Fdiv:
  case InstArithmetic::Frem:
    llvm::report_fatal_error("FP instruction with i64 type");
    return;
  case InstArithmetic::Udiv:
  case InstArithmetic::Sdiv:
  case InstArithmetic::Urem:
  case InstArithmetic::Srem:
    llvm::report_fatal_error("64-bit div and rem should have been prelowered");
    return;
  }
}

void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
  Variable *Dest = Instr->getDest();

  if (Dest->isRematerializable()) {
    Context.insert<InstFakeDef>(Dest);
    return;
  }

  // We need to signal all the UnimplementedLoweringError errors before any
  // legalization into new variables, otherwise Om1 register allocation may fail
  // when it sees variables that are defined but not used.
  Type DestTy = Dest->getType();
  Operand *Src0 = legalizeUndef(Instr->getSrc(0));
  Operand *Src1 = legalizeUndef(Instr->getSrc(1));
  if (DestTy == IceType_i64) {
    lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1);
    return;
  }
  if (isVectorType(Dest->getType())) {
    llvm::report_fatal_error("Arithmetic: Destination type is vector");
    return;
  }

  Variable *T = makeReg(Dest->getType());
  Variable *Src0R = legalizeToReg(Src0);
  Variable *Src1R = nullptr;
  uint32_t Value = 0;
  bool IsSrc1Imm16 = false;

  switch (Instr->getOp()) {
  case InstArithmetic::Add:
  case InstArithmetic::And:
  case InstArithmetic::Or:
  case InstArithmetic::Xor:
  case InstArithmetic::Sub:
  case InstArithmetic::Shl:
  case InstArithmetic::Lshr:
  case InstArithmetic::Ashr: {
    auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1);
    if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) {
      IsSrc1Imm16 = true;
      Value = Const32->getValue();
    } else {
      Src1R = legalizeToReg(Src1);
    }
    break;
  }
  default:
    Src1R = legalizeToReg(Src1);
    break;
  }
  constexpr uint32_t DivideByZeroTrapCode = 7;

  switch (Instr->getOp()) {
  case InstArithmetic::_num:
    break;
  case InstArithmetic::Add:
    if (IsSrc1Imm16) {
      _addiu(T, Src0R, Value);
    } else {
      _addu(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  case InstArithmetic::And:
    if (IsSrc1Imm16) {
      _andi(T, Src0R, Value);
    } else {
      _and(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  case InstArithmetic::Or:
    if (IsSrc1Imm16) {
      _ori(T, Src0R, Value);
    } else {
      _or(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  case InstArithmetic::Xor:
    if (IsSrc1Imm16) {
      _xori(T, Src0R, Value);
    } else {
      _xor(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  case InstArithmetic::Sub:
    if (IsSrc1Imm16) {
      _addiu(T, Src0R, -Value);
    } else {
      _subu(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  case InstArithmetic::Mul: {
    _mul(T, Src0R, Src1R);
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Shl: {
    if (IsSrc1Imm16) {
      _sll(T, Src0R, Value);
    } else {
      _sllv(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Lshr: {
    auto *T0R = Src0R;
    auto *T1R = Src1R;
    if (Dest->getType() != IceType_i32) {
      T0R = makeReg(IceType_i32);
      lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
      if (!IsSrc1Imm16) {
        T1R = makeReg(IceType_i32);
        lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
      }
    }
    if (IsSrc1Imm16) {
      _srl(T, T0R, Value);
    } else {
      _srlv(T, T0R, T1R);
    }
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Ashr: {
    if (IsSrc1Imm16) {
      _sra(T, Src0R, Value);
    } else {
      _srav(T, Src0R, Src1R);
    }
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Udiv: {
    auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
    auto *T0R = Src0R;
    auto *T1R = Src1R;
    if (Dest->getType() != IceType_i32) {
      T0R = makeReg(IceType_i32);
      lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
      T1R = makeReg(IceType_i32);
      lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
    }
    _divu(T_Zero, T0R, T1R);
    _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
    _mflo(T, T_Zero);
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Sdiv: {
    auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
    _div(T_Zero, Src0R, Src1R);
    _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
    _mflo(T, T_Zero);
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Urem: {
    auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
    auto *T0R = Src0R;
    auto *T1R = Src1R;
    if (Dest->getType() != IceType_i32) {
      T0R = makeReg(IceType_i32);
      lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
      T1R = makeReg(IceType_i32);
      lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
    }
    _divu(T_Zero, T0R, T1R);
    _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
    _mfhi(T, T_Zero);
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Srem: {
    auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
    _div(T_Zero, Src0R, Src1R);
    _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
    _mfhi(T, T_Zero);
    _mov(Dest, T);
    return;
  }
  case InstArithmetic::Fadd: {
    if (DestTy == IceType_f32) {
      _add_s(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    if (DestTy == IceType_f64) {
      _add_d(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    break;
  }
  case InstArithmetic::Fsub:
    if (DestTy == IceType_f32) {
      _sub_s(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    if (DestTy == IceType_f64) {
      _sub_d(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    break;
  case InstArithmetic::Fmul:
    if (DestTy == IceType_f32) {
      _mul_s(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    if (DestTy == IceType_f64) {
      _mul_d(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    break;
  case InstArithmetic::Fdiv:
    if (DestTy == IceType_f32) {
      _div_s(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    if (DestTy == IceType_f64) {
      _div_d(T, Src0R, Src1R);
      _mov(Dest, T);
      return;
    }
    break;
  case InstArithmetic::Frem:
    llvm::report_fatal_error("frem should have been prelowered.");
    break;
  }
  llvm::report_fatal_error("Unknown arithmetic operator");
}

void TargetMIPS32::lowerAssign(const InstAssign *Instr) {
  Variable *Dest = Instr->getDest();

  if (Dest->isRematerializable()) {
    Context.insert<InstFakeDef>(Dest);
    return;
  }

  // Source type may not be same as destination
  if (isVectorType(Dest->getType())) {
    Operand *Src0 = legalizeUndef(Instr->getSrc(0));
    auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest);
    for (SizeT i = 0; i < DstVec->ContainersPerVector; ++i) {
      auto *DCont = DstVec->getContainers()[i];
      auto *SCont =
          legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg);
      auto *TReg = makeReg(IceType_i32);
      _mov(TReg, SCont);
      _mov(DCont, TReg);
    }
    return;
  }
  Operand *Src0 = Instr->getSrc(0);
  assert(Dest->getType() == Src0->getType());
  if (Dest->getType() == IceType_i64) {
    Src0 = legalizeUndef(Src0);
    Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
    Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
    auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
    auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
    auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
    _mov(T_Lo, Src0Lo);
    _mov(DestLo, T_Lo);
    _mov(T_Hi, Src0Hi);
    _mov(DestHi, T_Hi);
    return;
  }
  Operand *SrcR;
  if (Dest->hasReg()) {
    // If Dest already has a physical register, then legalize the Src operand
    // into a Variable with the same register assignment.  This especially
    // helps allow the use of Flex operands.
    SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum());
  } else {
    // Dest could be a stack operand. Since we could potentially need
    // to do a Store (and store can only have Register operands),
    // legalize this to a register.
    SrcR = legalize(Src0, Legal_Reg);
  }
  _mov(Dest, SrcR);
}

void TargetMIPS32::lowerBr(const InstBr *Instr) {
  if (Instr->isUnconditional()) {
    _br(Instr->getTargetUnconditional());
    return;
  }
  CfgNode *TargetTrue = Instr->getTargetTrue();
  CfgNode *TargetFalse = Instr->getTargetFalse();
  Operand *Boolean = Instr->getCondition();
  const Inst *Producer = Computations.getProducerOf(Boolean);
  if (Producer == nullptr) {
    // Since we don't know the producer of this boolean we will assume its
    // producer will keep it in positive logic and just emit beqz with this
    // Boolean as an operand.
    auto *BooleanR = legalizeToReg(Boolean);
    _br(TargetTrue, TargetFalse, BooleanR, CondMIPS32::Cond::EQZ);
    return;
  }
  if (Producer->getKind() == Inst::Icmp) {
    const InstIcmp *CompareInst = llvm::cast<InstIcmp>(Producer);
    Operand *Src0 = CompareInst->getSrc(0);
    Operand *Src1 = CompareInst->getSrc(1);
    const Type Src0Ty = Src0->getType();
    assert(Src0Ty == Src1->getType());

    Variable *Src0R = nullptr;
    Variable *Src1R = nullptr;
    Variable *Src0HiR = nullptr;
    Variable *Src1HiR = nullptr;
    if (Src0Ty == IceType_i64) {
      Src0R = legalizeToReg(loOperand(Src0));
      Src1R = legalizeToReg(loOperand(Src1));
      Src0HiR = legalizeToReg(hiOperand(Src0));
      Src1HiR = legalizeToReg(hiOperand(Src1));
    } else {
      Src0R = legalizeToReg(Src0);
      Src1R = legalizeToReg(Src1);
    }
    auto *DestT = makeReg(IceType_i32);

    switch (CompareInst->getCondition()) {
    default:
      llvm_unreachable("unexpected condition");
      return;
    case InstIcmp::Eq: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _xor(T2, Src0R, Src1R);
        _or(T3, T1, T2);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::NE);
      }
      return;
    }
    case InstIcmp::Ne: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _xor(T2, Src0R, Src1R);
        _or(T3, T1, T2);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ);
      } else {
        _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::EQ);
      }
      return;
    }
    case InstIcmp::Ugt: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        auto *T4 = I32Reg();
        auto *T5 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _sltu(T2, Src1HiR, Src0HiR);
        _xori(T3, T2, 1);
        _sltu(T4, Src1R, Src0R);
        _xori(T5, T4, 1);
        _movz(T3, T5, T1);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _sltu(DestT, Src1R, Src0R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ);
      }
      return;
    }
    case InstIcmp::Uge: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _sltu(T2, Src0HiR, Src1HiR);
        _sltu(T3, Src0R, Src1R);
        _movz(T2, T3, T1);
        _mov(DestT, T2);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _sltu(DestT, Src0R, Src1R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      }
      return;
    }
    case InstIcmp::Ult: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        auto *T4 = I32Reg();
        auto *T5 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _sltu(T2, Src0HiR, Src1HiR);
        _xori(T3, T2, 1);
        _sltu(T4, Src0R, Src1R);
        _xori(T5, T4, 1);
        _movz(T3, T5, T1);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _sltu(DestT, Src0R, Src1R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ);
      }
      return;
    }
    case InstIcmp::Ule: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _sltu(T2, Src1HiR, Src0HiR);
        _sltu(T3, Src1R, Src0R);
        _movz(T2, T3, T1);
        _mov(DestT, T2);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _sltu(DestT, Src1R, Src0R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      }
      return;
    }
    case InstIcmp::Sgt: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        auto *T4 = I32Reg();
        auto *T5 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _slt(T2, Src1HiR, Src0HiR);
        _xori(T3, T2, 1);
        _sltu(T4, Src1R, Src0R);
        _xori(T5, T4, 1);
        _movz(T3, T5, T1);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _slt(DestT, Src1R, Src0R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ);
      }
      return;
    }
    case InstIcmp::Sge: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _slt(T2, Src0HiR, Src1HiR);
        _sltu(T3, Src0R, Src1R);
        _movz(T2, T3, T1);
        _mov(DestT, T2);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _slt(DestT, Src0R, Src1R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      }
      return;
    }
    case InstIcmp::Slt: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        auto *T4 = I32Reg();
        auto *T5 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _slt(T2, Src0HiR, Src1HiR);
        _xori(T3, T2, 1);
        _sltu(T4, Src0R, Src1R);
        _xori(T5, T4, 1);
        _movz(T3, T5, T1);
        _mov(DestT, T3);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _slt(DestT, Src0R, Src1R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ);
      }
      return;
    }
    case InstIcmp::Sle: {
      if (Src0Ty == IceType_i64) {
        auto *T1 = I32Reg();
        auto *T2 = I32Reg();
        auto *T3 = I32Reg();
        _xor(T1, Src0HiR, Src1HiR);
        _slt(T2, Src1HiR, Src0HiR);
        _sltu(T3, Src1R, Src0R);
        _movz(T2, T3, T1);
        _mov(DestT, T2);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      } else {
        _slt(DestT, Src1R, Src0R);
        _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
      }
      return;
    }
    }
  }
}

void TargetMIPS32::lowerCall(const InstCall *Instr) {
  CfgVector<Variable *> RegArgs;
  NeedsStackAlignment = true;

  //  Assign arguments to registers and stack. Also reserve stack.
  TargetMIPS32::CallingConv CC;

  // Pair of Arg Operand -> GPR number assignments.
  llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_GPR_ARG> GPRArgs;
  llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_FP_ARG> FPArgs;
  // Pair of Arg Operand -> stack offset.
  llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
  size_t ParameterAreaSizeBytes = 16;

  // Classify each argument operand according to the location where the
  // argument is passed.

  // v4f32 is returned through stack. $4 is setup by the caller and passed as
  // first argument implicitly. Callee then copies the return vector at $4.
  SizeT ArgNum = 0;
  Variable *Dest = Instr->getDest();
  Variable *RetVecFloat = nullptr;
  if (Dest && isVectorFloatingType(Dest->getType())) {
    ArgNum = 1;
    CC.discardReg(RegMIPS32::Reg_A0);
    RetVecFloat = Func->makeVariable(IceType_i32);
    auto *ByteCount = ConstantInteger32::create(Ctx, IceType_i32, 16);
    constexpr SizeT Alignment = 4;
    lowerAlloca(InstAlloca::create(Func, RetVecFloat, ByteCount, Alignment));
    RegArgs.emplace_back(
        legalizeToReg(RetVecFloat, RegNumT::fixme(RegMIPS32::Reg_A0)));
  }

  for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
    Operand *Arg = legalizeUndef(Instr->getArg(i));
    const Type Ty = Arg->getType();
    bool InReg = false;
    RegNumT Reg;

    InReg = CC.argInReg(Ty, i, &Reg);

    if (!InReg) {
      if (isVectorType(Ty)) {
        auto *ArgVec = llvm::cast<VariableVecOn32>(Arg);
        for (Variable *Elem : ArgVec->getContainers()) {
          ParameterAreaSizeBytes =
              applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
          StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes));
          ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
        }
      } else {
        ParameterAreaSizeBytes =
            applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
        StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
        ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
      }
      ++ArgNum;
      continue;
    }

    if (isVectorType(Ty)) {
      auto *ArgVec = llvm::cast<VariableVecOn32>(Arg);
      Operand *Elem0 = ArgVec->getContainers()[0];
      Operand *Elem1 = ArgVec->getContainers()[1];
      GPRArgs.push_back(
          std::make_pair(Elem0, RegNumT::fixme((unsigned)Reg + 0)));
      GPRArgs.push_back(
          std::make_pair(Elem1, RegNumT::fixme((unsigned)Reg + 1)));
      Operand *Elem2 = ArgVec->getContainers()[2];
      Operand *Elem3 = ArgVec->getContainers()[3];
      // First argument is passed in $4:$5:$6:$7
      // Second and rest arguments are passed in $6:$7:stack:stack
      if (ArgNum == 0) {
        GPRArgs.push_back(
            std::make_pair(Elem2, RegNumT::fixme((unsigned)Reg + 2)));
        GPRArgs.push_back(
            std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3)));
      } else {
        ParameterAreaSizeBytes =
            applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
        StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes));
        ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
        ParameterAreaSizeBytes =
            applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
        StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes));
        ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
      }
    } else if (Ty == IceType_i64) {
      Operand *Lo = loOperand(Arg);
      Operand *Hi = hiOperand(Arg);
      GPRArgs.push_back(
          std::make_pair(Lo, RegMIPS32::get64PairFirstRegNum(Reg)));
      GPRArgs.push_back(
          std::make_pair(Hi, RegMIPS32::get64PairSecondRegNum(Reg)));
    } else if (isScalarIntegerType(Ty)) {
      GPRArgs.push_back(std::make_pair(Arg, Reg));
    } else {
      FPArgs.push_back(std::make_pair(Arg, Reg));
    }
    ++ArgNum;
  }

  // Adjust the parameter area so that the stack is aligned. It is assumed that
  // the stack is already aligned at the start of the calling sequence.
  ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);

  // Copy arguments that are passed on the stack to the appropriate stack
  // locations.
  Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
  for (auto &StackArg : StackArgs) {
    ConstantInteger32 *Loc =
        llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackArg.second));
    Type Ty = StackArg.first->getType();
    OperandMIPS32Mem *Addr;
    constexpr bool SignExt = false;
    if (OperandMIPS32Mem::canHoldOffset(Ty, SignExt, StackArg.second)) {
      Addr = OperandMIPS32Mem::create(Func, Ty, SP, Loc);
    } else {
      Variable *NewBase = Func->makeVariable(SP->getType());
      lowerArithmetic(
          InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc));
      Addr = formMemoryOperand(NewBase, Ty);
    }
    lowerStore(InstStore::create(Func, StackArg.first, Addr));
  }

  // Generate the call instruction.  Assign its result to a temporary with high
  // register allocation weight.

  // ReturnReg doubles as ReturnRegLo as necessary.
  Variable *ReturnReg = nullptr;
  Variable *ReturnRegHi = nullptr;
  if (Dest) {
    switch (Dest->getType()) {
    case IceType_NUM:
      llvm_unreachable("Invalid Call dest type");
      return;
    case IceType_void:
      break;
    case IceType_i1:
    case IceType_i8:
    case IceType_i16:
    case IceType_i32:
      ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0);
      break;
    case IceType_i64:
      ReturnReg = I32Reg(RegMIPS32::Reg_V0);
      ReturnRegHi = I32Reg(RegMIPS32::Reg_V1);
      break;
    case IceType_f32:
      ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_F0);
      break;
    case IceType_f64:
      ReturnReg = makeReg(IceType_f64, RegMIPS32::Reg_F0);
      break;
    case IceType_v4i1:
    case IceType_v8i1:
    case IceType_v16i1:
    case IceType_v16i8:
    case IceType_v8i16:
    case IceType_v4i32: {
      ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0);
      auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg);
      RetVec->initVecElement(Func);
      for (SizeT i = 0; i < RetVec->ContainersPerVector; ++i) {
        auto *Var = RetVec->getContainers()[i];
        Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i));
      }
      break;
    }
    case IceType_v4f32:
      ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0);
      break;
    }
  }
  Operand *CallTarget = Instr->getCallTarget();
  // Allow ConstantRelocatable to be left alone as a direct call,
  // but force other constants like ConstantInteger32 to be in
  // a register and make it an indirect call.
  if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
    CallTarget = legalize(CallTarget, Legal_Reg);
  }

  // Copy arguments to be passed in registers to the appropriate registers.
  for (auto &FPArg : FPArgs) {
    RegArgs.emplace_back(legalizeToReg(FPArg.first, FPArg.second));
  }
  for (auto &GPRArg : GPRArgs) {
    RegArgs.emplace_back(legalizeToReg(GPRArg.first, GPRArg.second));
  }

  // Generate a FakeUse of register arguments so that they do not get dead code
  // eliminated as a result of the FakeKill of scratch registers after the call.
  // These fake-uses need to be placed here to avoid argument registers from
  // being used during the legalizeToReg() calls above.
  for (auto *RegArg : RegArgs) {
    Context.insert<InstFakeUse>(RegArg);
  }

  // If variable alloca is used the extra 16 bytes for argument build area
  // will be allocated on stack before a call.
  if (VariableAllocaUsed)
    Sandboxer(this).addiu_sp(-MaxOutArgsSizeBytes);

  Inst *NewCall;

  // We don't need to define the return register if it is a vector.
  // We have inserted fake defs of it just after the call.
  if (ReturnReg && isVectorIntegerType(ReturnReg->getType())) {
    Variable *RetReg = nullptr;
    NewCall = InstMIPS32Call::create(Func, RetReg, CallTarget);
    Context.insert(NewCall);
  } else {
    NewCall = Sandboxer(this, InstBundleLock::Opt_AlignToEnd)
                  .jal(ReturnReg, CallTarget);
  }

  if (VariableAllocaUsed)
    Sandboxer(this).addiu_sp(MaxOutArgsSizeBytes);

  // Insert a fake use of stack pointer to avoid dead code elimination of addiu
  // instruction.
  Context.insert<InstFakeUse>(SP);

  if (ReturnRegHi)
    Context.insert(InstFakeDef::create(Func, ReturnRegHi));

  if (ReturnReg) {
    if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) {
      for (Variable *Var : RetVec->getContainers()) {
        Context.insert(InstFakeDef::create(Func, Var));
      }
    }
  }

  // Insert a register-kill pseudo instruction.
  Context.insert(InstFakeKill::create(Func, NewCall));

  // Generate a FakeUse to keep the call live if necessary.
  if (Instr->hasSideEffects() && ReturnReg) {
    if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) {
      for (Variable *Var : RetVec->getContainers()) {
        Context.insert<InstFakeUse>(Var);
      }
    } else {
      Context.insert<InstFakeUse>(ReturnReg);
    }
  }

  if (Dest == nullptr)
    return;

  // Assign the result of the call to Dest.
  if (ReturnReg) {
    if (RetVecFloat) {
      auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest);
      auto *TBase = legalizeToReg(RetVecFloat);
      for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) {
        auto *Var = DestVecOn32->getContainers()[i];
        auto *TVar = makeReg(IceType_i32);
        OperandMIPS32Mem *Mem = OperandMIPS32Mem::create(
            Func, IceType_i32, TBase,
            llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4)));
        _lw(TVar, Mem);
        _mov(Var, TVar);
      }
    } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) {
      auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest);
      for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) {
        _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]);
      }
    } else if (ReturnRegHi) {
      assert(Dest->getType() == IceType_i64);
      auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
      Variable *DestLo = Dest64On32->getLo();
      Variable *DestHi = Dest64On32->getHi();
      _mov(DestLo, ReturnReg);
      _mov(DestHi, ReturnRegHi);
    } else {
      assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 ||
             Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 ||
             isScalarFloatingType(Dest->getType()) ||
             isVectorType(Dest->getType()));
      _mov(Dest, ReturnReg);
    }
  }
}

void TargetMIPS32::lowerCast(const InstCast *Instr) {
  InstCast::OpKind CastKind = Instr->getCastKind();
  Variable *Dest = Instr->getDest();
  Operand *Src0 = legalizeUndef(Instr->getSrc(0));
  const Type DestTy = Dest->getType();
  const Type Src0Ty = Src0->getType();
  const uint32_t ShiftAmount =
      (Src0Ty == IceType_i1
           ? INT32_BITS - 1
           : INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty)));
  const uint32_t Mask =
      (Src0Ty == IceType_i1
           ? 1
           : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1);

  if (isVectorType(DestTy)) {
    llvm::report_fatal_error("Cast: Destination type is vector");
    return;
  }
  switch (CastKind) {
  default:
    Func->setError("Cast type not supported");
    return;
  case InstCast::Sext: {
    if (DestTy == IceType_i64) {
      auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
      auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
      Variable *Src0R = legalizeToReg(Src0);
      Variable *T1_Lo = I32Reg();
      Variable *T2_Lo = I32Reg();
      Variable *T_Hi = I32Reg();
      if (Src0Ty == IceType_i1) {
        _sll(T1_Lo, Src0R, INT32_BITS - 1);
        _sra(T2_Lo, T1_Lo, INT32_BITS - 1);
        _mov(DestHi, T2_Lo);
        _mov(DestLo, T2_Lo);
      } else if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) {
        _sll(T1_Lo, Src0R, ShiftAmount);
        _sra(T2_Lo, T1_Lo, ShiftAmount);
        _sra(T_Hi, T2_Lo, INT32_BITS - 1);
        _mov(DestHi, T_Hi);
        _mov(DestLo, T2_Lo);
      } else if (Src0Ty == IceType_i32) {
        _mov(T1_Lo, Src0R);
        _sra(T_Hi, T1_Lo, INT32_BITS - 1);
        _mov(DestHi, T_Hi);
        _mov(DestLo, T1_Lo);
      }
    } else {
      Variable *Src0R = legalizeToReg(Src0);
      Variable *T1 = makeReg(DestTy);
      Variable *T2 = makeReg(DestTy);
      if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 ||
          Src0Ty == IceType_i16) {
        _sll(T1, Src0R, ShiftAmount);
        _sra(T2, T1, ShiftAmount);
        _mov(Dest, T2);
      }
    }
    break;
  }
  case InstCast::Zext: {
    if (DestTy == IceType_i64) {
      auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
      auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
      Variable *Src0R = legalizeToReg(Src0);
      Variable *T_Lo = I32Reg();
      Variable *T_Hi = I32Reg();

      if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 || Src0Ty == IceType_i16)
        _andi(T_Lo, Src0R, Mask);
      else if (Src0Ty == IceType_i32)
        _mov(T_Lo, Src0R);
      else
        assert(Src0Ty != IceType_i64);
      _mov(DestLo, T_Lo);

      auto *Zero = getZero();
      _addiu(T_Hi, Zero, 0);
      _mov(DestHi, T_Hi);
    } else {
      Variable *Src0R = legalizeToReg(Src0);
      Variable *T = makeReg(DestTy);
      if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 ||
          Src0Ty == IceType_i16) {
        _andi(T, Src0R, Mask);
        _mov(Dest, T);
      }
    }
    break;
  }
  case InstCast::Trunc: {
    if (Src0Ty == IceType_i64)
      Src0 = loOperand(Src0);
    Variable *Src0R = legalizeToReg(Src0);
    Variable *T = makeReg(DestTy);
    _mov(T, Src0R);
    _mov(Dest, T);
    break;
  }
  case InstCast::Fptrunc: {
    assert(Dest->getType() == IceType_f32);
    assert(Src0->getType() == IceType_f64);
    auto *DestR = legalizeToReg(Dest);
    auto *Src0R = legalizeToReg(Src0);
    _cvt_s_d(DestR, Src0R);
    _mov(Dest, DestR);
    break;
  }
  case InstCast::Fpext: {
    assert(Dest->getType() == IceType_f64);
    assert(Src0->getType() == IceType_f32);
    auto *DestR = legalizeToReg(Dest);
    auto *Src0R = legalizeToReg(Src0);
    _cvt_d_s(DestR, Src0R);
    _mov(Dest, DestR);
    break;
  }
  case InstCast::Fptosi:
  case InstCast::Fptoui: {
    if (llvm::isa<Variable64On32>(Dest)) {
      llvm::report_fatal_error("fp-to-i64 should have been prelowered.");
      return;
    }
    if (DestTy != IceType_i64) {
      if (Src0Ty == IceType_f32 && isScalarIntegerType(DestTy)) {
        Variable *Src0R = legalizeToReg(Src0);
        Variable *FTmp = makeReg(IceType_f32);
        _trunc_w_s(FTmp, Src0R);
        _mov(Dest, FTmp);
        return;
      }
      if (Src0Ty == IceType_f64 && isScalarIntegerType(DestTy)) {
        Variable *Src0R = legalizeToReg(Src0);
        Variable *FTmp = makeReg(IceType_f64);
        _trunc_w_d(FTmp, Src0R);
        _mov(Dest, FTmp);
        return;
      }
    }
    llvm::report_fatal_error("Destination is i64 in fp-to-i32");
    break;
  }
  case InstCast::Sitofp:
  case InstCast::Uitofp: {
    if (llvm::isa<Variable64On32>(Dest)) {
      llvm::report_fatal_error("i64-to-fp should have been prelowered.");
      return;
    }
    if (Src0Ty != IceType_i64) {
      Variable *Src0R = legalizeToReg(Src0);
      auto *T0R = Src0R;
      if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) {
        T0R = makeReg(IceType_i32);
        lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
      }
      if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) {
        Variable *FTmp1 = makeReg(IceType_f32);
        Variable *FTmp2 = makeReg(IceType_f32);
        _mtc1(FTmp1, T0R);
        _cvt_s_w(FTmp2, FTmp1);
        _mov(Dest, FTmp2);
        return;
      }
      if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) {
        Variable *FTmp1 = makeReg(IceType_f64);
        Variable *FTmp2 = makeReg(IceType_f64);
        _mtc1(FTmp1, T0R);
        _cvt_d_w(FTmp2, FTmp1);
        _mov(Dest, FTmp2);
        return;
      }
    }
    llvm::report_fatal_error("Source is i64 in i32-to-fp");
    break;
  }
  case InstCast::Bitcast: {
    Operand *Src0 = Instr->getSrc(0);
    if (DestTy == Src0->getType()) {
      auto *Assign = InstAssign::create(Func, Dest, Src0);
      lowerAssign(Assign);
      return;
    }
    if (isVectorType(DestTy) || isVectorType(Src0->getType())) {
      llvm::report_fatal_error(
          "Bitcast: vector type should have been prelowered.");
      return;
    }
    switch (DestTy) {
    case IceType_NUM:
    case IceType_void:
      llvm::report_fatal_error("Unexpected bitcast.");
    case IceType_i1:
      UnimplementedLoweringError(this, Instr);
      break;
    case IceType_i8:
      assert(Src0->getType() == IceType_v8i1);
      llvm::report_fatal_error(
          "i8 to v8i1 conversion should have been prelowered.");
      break;
    case IceType_i16:
      assert(Src0->getType() == IceType_v16i1);
      llvm::report_fatal_error(
          "i16 to v16i1 conversion should have been prelowered.");
      break;
    case IceType_i32:
    case IceType_f32: {
      Variable *Src0R = legalizeToReg(Src0);
      _mov(Dest, Src0R);
      break;
    }
    case IceType_i64: {
      assert(Src0->getType() == IceType_f64);
      Variable *Src0R = legalizeToReg(Src0);
      auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
      T->initHiLo(Func);
      T->getHi()->setMustHaveReg();
      T->getLo()->setMustHaveReg();
      _mov(T, Src0R);
      lowerAssign(InstAssign::create(Func, Dest, T));
      break;
    }
    case IceType_f64: {
      assert(Src0->getType() == IceType_i64);
      const uint32_t Mask = 0xFFFFFFFF;
      if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) {
        Variable *RegHi, *RegLo;
        const uint64_t Value = C64->getValue();
        uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask;
        uint64_t Lower32Bits = Value & Mask;
        RegLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits));
        RegHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits));
        _mov(Dest, RegHi, RegLo);
      } else {
        auto *Var64On32 = llvm::cast<Variable64On32>(Src0);
        auto *RegLo = legalizeToReg(loOperand(Var64On32));
        auto *RegHi = legalizeToReg(hiOperand(Var64On32));
        _mov(Dest, RegHi, RegLo);
      }
      break;
    }
    default:
      llvm::report_fatal_error("Unexpected bitcast.");
    }
    break;
  }
  }
}

void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) {
  Variable *Dest = Instr->getDest();
  const Type DestTy = Dest->getType();
  Operand *Src1 = Instr->getSrc(1);
  if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) {
    const uint32_t Index = Imm->getValue();
    Variable *TDest = makeReg(DestTy);
    Variable *TReg = makeReg(DestTy);
    auto *Src0 = legalizeUndef(Instr->getSrc(0));
    auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0);
    // Number of elements in each container
    uint32_t ElemPerCont =
        typeNumElements(Src0->getType()) / Src0R->ContainersPerVector;
    auto *Src = Src0R->getContainers()[Index / ElemPerCont];
    auto *SrcE = legalizeToReg(Src);
    // Position of the element in the container
    uint32_t PosInCont = Index % ElemPerCont;
    if (ElemPerCont == 1) {
      _mov(TDest, SrcE);
    } else if (ElemPerCont == 2) {
      switch (PosInCont) {
      case 0:
        _andi(TDest, SrcE, 0xffff);
        break;
      case 1:
        _srl(TDest, SrcE, 16);
        break;
      default:
        llvm::report_fatal_error("ExtractElement: Invalid PosInCont");
        break;
      }
    } else if (ElemPerCont == 4) {
      switch (PosInCont) {
      case 0:
        _andi(TDest, SrcE, 0xff);
        break;
      case 1:
        _srl(TReg, SrcE, 8);
        _andi(TDest, TReg, 0xff);
        break;
      case 2:
        _srl(TReg, SrcE, 16);
        _andi(TDest, TReg, 0xff);
        break;
      case 3:
        _srl(TDest, SrcE, 24);
        break;
      default:
        llvm::report_fatal_error("ExtractElement: Invalid PosInCont");
        break;
      }
    }
    if (typeElementType(Src0R->getType()) == IceType_i1) {
      Variable *TReg1 = makeReg(DestTy);
      _andi(TReg1, TDest, 0x1);
      _mov(Dest, TReg1);
    } else {
      _mov(Dest, TDest);
    }
    return;
  }
  llvm::report_fatal_error("ExtractElement requires a constant index");
}

void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) {
  Variable *Dest = Instr->getDest();
  if (isVectorType(Dest->getType())) {
    llvm::report_fatal_error("Fcmp: Destination type is vector");
    return;
  }

  auto *Src0 = Instr->getSrc(0);
  auto *Src1 = Instr->getSrc(1);
  auto *Zero = getZero();

  InstFcmp::FCond Cond = Instr->getCondition();
  auto *DestR = makeReg(IceType_i32);
  auto *Src0R = legalizeToReg(Src0);
  auto *Src1R = legalizeToReg(Src1);
  const Type Src0Ty = Src0->getType();

  Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0);

  switch (Cond) {
  default: {
    llvm::report_fatal_error("Unhandled fp comparison.");
    return;
  }
  case InstFcmp::False: {
    Context.insert<InstFakeUse>(Src0R);
    Context.insert<InstFakeUse>(Src1R);
    _addiu(DestR, Zero, 0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Oeq: {
    if (Src0Ty == IceType_f32) {
      _c_eq_s(Src0R, Src1R);
    } else {
      _c_eq_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ogt: {
    if (Src0Ty == IceType_f32) {
      _c_ule_s(Src0R, Src1R);
    } else {
      _c_ule_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Oge: {
    if (Src0Ty == IceType_f32) {
      _c_ult_s(Src0R, Src1R);
    } else {
      _c_ult_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Olt: {
    if (Src0Ty == IceType_f32) {
      _c_olt_s(Src0R, Src1R);
    } else {
      _c_olt_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ole: {
    if (Src0Ty == IceType_f32) {
      _c_ole_s(Src0R, Src1R);
    } else {
      _c_ole_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::One: {
    if (Src0Ty == IceType_f32) {
      _c_ueq_s(Src0R, Src1R);
    } else {
      _c_ueq_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ord: {
    if (Src0Ty == IceType_f32) {
      _c_un_s(Src0R, Src1R);
    } else {
      _c_un_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ueq: {
    if (Src0Ty == IceType_f32) {
      _c_ueq_s(Src0R, Src1R);
    } else {
      _c_ueq_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ugt: {
    if (Src0Ty == IceType_f32) {
      _c_ole_s(Src0R, Src1R);
    } else {
      _c_ole_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Uge: {
    if (Src0Ty == IceType_f32) {
      _c_olt_s(Src0R, Src1R);
    } else {
      _c_olt_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ult: {
    if (Src0Ty == IceType_f32) {
      _c_ult_s(Src0R, Src1R);
    } else {
      _c_ult_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Ule: {
    if (Src0Ty == IceType_f32) {
      _c_ule_s(Src0R, Src1R);
    } else {
      _c_ule_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Une: {
    if (Src0Ty == IceType_f32) {
      _c_eq_s(Src0R, Src1R);
    } else {
      _c_eq_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movt(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::Uno: {
    if (Src0Ty == IceType_f32) {
      _c_un_s(Src0R, Src1R);
    } else {
      _c_un_d(Src0R, Src1R);
    }
    _addiu(DestR, Zero, 1);
    _movf(DestR, Zero, FCC0);
    _mov(Dest, DestR);
    break;
  }
  case InstFcmp::True: {
    Context.insert<InstFakeUse>(Src0R);
    Context.insert<InstFakeUse>(Src1R);
    _addiu(DestR, Zero, 1);
    _mov(Dest, DestR);
    break;
  }
  }
}

void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) {
  Operand *Src0 = legalize(Instr->getSrc(0));
  Operand *Src1 = legalize(Instr->getSrc(1));
  Variable *Dest = Instr->getDest();
  InstIcmp::ICond Condition = Instr->getCondition();

  Variable *Src0LoR = legalizeToReg(loOperand(Src0));
  Variable *Src0HiR = legalizeToReg(hiOperand(Src0));
  Variable *Src1LoR = legalizeToReg(loOperand(Src1));
  Variable *Src1HiR = legalizeToReg(hiOperand(Src1));

  switch (Condition) {
  default:
    llvm_unreachable("unexpected condition");
    return;
  case InstIcmp::Eq: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _xor(T2, Src0LoR, Src1LoR);
    _or(T3, T1, T2);
    _sltiu(T4, T3, 1);
    _mov(Dest, T4);
    return;
  }
  case InstIcmp::Ne: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _xor(T2, Src0LoR, Src1LoR);
    _or(T3, T1, T2);
    _sltu(T4, getZero(), T3);
    _mov(Dest, T4);
    return;
  }
  case InstIcmp::Sgt: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _slt(T2, Src1HiR, Src0HiR);
    _sltu(T3, Src1LoR, Src0LoR);
    _movz(T2, T3, T1);
    _mov(Dest, T2);
    return;
  }
  case InstIcmp::Ugt: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _sltu(T2, Src1HiR, Src0HiR);
    _sltu(T3, Src1LoR, Src0LoR);
    _movz(T2, T3, T1);
    _mov(Dest, T2);
    return;
  }
  case InstIcmp::Sge: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _slt(T2, Src0HiR, Src1HiR);
    _xori(T3, T2, 1);
    _sltu(T4, Src0LoR, Src1LoR);
    _xori(T5, T4, 1);
    _movz(T3, T5, T1);
    _mov(Dest, T3);
    return;
  }
  case InstIcmp::Uge: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _sltu(T2, Src0HiR, Src1HiR);
    _xori(T3, T2, 1);
    _sltu(T4, Src0LoR, Src1LoR);
    _xori(T5, T4, 1);
    _movz(T3, T5, T1);
    _mov(Dest, T3);
    return;
  }
  case InstIcmp::Slt: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _slt(T2, Src0HiR, Src1HiR);
    _sltu(T3, Src0LoR, Src1LoR);
    _movz(T2, T3, T1);
    _mov(Dest, T2);
    return;
  }
  case InstIcmp::Ult: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _sltu(T2, Src0HiR, Src1HiR);
    _sltu(T3, Src0LoR, Src1LoR);
    _movz(T2, T3, T1);
    _mov(Dest, T2);
    return;
  }
  case InstIcmp::Sle: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _slt(T2, Src1HiR, Src0HiR);
    _xori(T3, T2, 1);
    _sltu(T4, Src1LoR, Src0LoR);
    _xori(T5, T4, 1);
    _movz(T3, T5, T1);
    _mov(Dest, T3);
    return;
  }
  case InstIcmp::Ule: {
    auto *T1 = I32Reg();
    auto *T2 = I32Reg();
    auto *T3 = I32Reg();
    auto *T4 = I32Reg();
    auto *T5 = I32Reg();
    _xor(T1, Src0HiR, Src1HiR);
    _sltu(T2, Src1HiR, Src0HiR);
    _xori(T3, T2, 1);
    _sltu(T4, Src1LoR, Src0LoR);
    _xori(T5, T4, 1);
    _movz(T3, T5, T1);
    _mov(Dest, T3);
    return;
  }
  }
}

void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
  auto *Src0 = Instr->getSrc(0);
  auto *Src1 = Instr->getSrc(1);
  if (Src0->getType() == IceType_i64) {
    lower64Icmp(Instr);
    return;
  }
  Variable *Dest = Instr->getDest();
  if (isVectorType(Dest->getType())) {
    llvm::report_fatal_error("Icmp: Destination type is vector");
    return;
  }
  InstIcmp::ICond Cond = Instr->getCondition();
  auto *Src0R = legalizeToReg(Src0);
  auto *Src1R = legalizeToReg(Src1);
  const Type Src0Ty = Src0R->getType();
  const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType());
  Variable *Src0RT = I32Reg();
  Variable *Src1RT = I32Reg();

  if (Src0Ty != IceType_i32) {
    _sll(Src0RT, Src0R, ShAmt);
    _sll(Src1RT, Src1R, ShAmt);
  } else {
    _mov(Src0RT, Src0R);
    _mov(Src1RT, Src1R);
  }

  switch (Cond) {
  case InstIcmp::Eq: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    _xor(T, Src0RT, Src1RT);
    _sltiu(DestT, T, 1);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Ne: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    auto *Zero = getZero();
    _xor(T, Src0RT, Src1RT);
    _sltu(DestT, Zero, T);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Ugt: {
    auto *DestT = I32Reg();
    _sltu(DestT, Src1RT, Src0RT);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Uge: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    _sltu(T, Src0RT, Src1RT);
    _xori(DestT, T, 1);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Ult: {
    auto *DestT = I32Reg();
    _sltu(DestT, Src0RT, Src1RT);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Ule: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    _sltu(T, Src1RT, Src0RT);
    _xori(DestT, T, 1);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Sgt: {
    auto *DestT = I32Reg();
    _slt(DestT, Src1RT, Src0RT);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Sge: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    _slt(T, Src0RT, Src1RT);
    _xori(DestT, T, 1);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Slt: {
    auto *DestT = I32Reg();
    _slt(DestT, Src0RT, Src1RT);
    _mov(Dest, DestT);
    return;
  }
  case InstIcmp::Sle: {
    auto *DestT = I32Reg();
    auto *T = I32Reg();
    _slt(T, Src1RT, Src0RT);
    _xori(DestT, T, 1);
    _mov(Dest, DestT);
    return;
  }
  default:
    llvm_unreachable("Invalid ICmp operator");
    return;
  }
}

void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
  Variable *Dest = Instr->getDest();
  const Type DestTy = Dest->getType();
  Operand *Src2 = Instr->getSrc(2);
  if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) {
    const uint32_t Index = Imm->getValue();
    // Vector to insert in
    auto *Src0 = legalizeUndef(Instr->getSrc(0));
    auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0);
    // Number of elements in each container
    uint32_t ElemPerCont =
        typeNumElements(Src0->getType()) / Src0R->ContainersPerVector;
    // Source Element
    auto *Src = Src0R->getContainers()[Index / ElemPerCont];
    auto *SrcE = Src;
    if (ElemPerCont > 1)
      SrcE = legalizeToReg(Src);
    // Dest is a vector
    auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest);
    VDest->initVecElement(Func);
    // Temp vector variable
    auto *TDest = makeReg(DestTy);
    auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest);
    TVDest->initVecElement(Func);
    // Destination element
    auto *DstE = TVDest->getContainers()[Index / ElemPerCont];
    // Element to insert
    auto *Src1R = legalizeToReg(Instr->getSrc(1));
    auto *TReg1 = makeReg(Src1R->getType());
    auto *TReg2 = makeReg(Src1R->getType());
    auto *TReg3 = makeReg(Src1R->getType());
    auto *TReg4 = makeReg(Src1R->getType());
    auto *TReg5 = makeReg(Src1R->getType());
    auto *TDReg = makeReg(Src1R->getType());
    // Position of the element in the container
    uint32_t PosInCont = Index % ElemPerCont;
    // Load source vector in a temporary vector
    for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) {
      auto *DCont = TVDest->getContainers()[i];
      // Do not define DstE as we are going to redefine it
      if (DCont == DstE)
        continue;
      auto *SCont = Src0R->getContainers()[i];
      auto *TReg = makeReg(IceType_i32);
      _mov(TReg, SCont);
      _mov(DCont, TReg);
    }
    // Insert the element
    if (ElemPerCont == 1) {
      _mov(DstE, Src1R);
    } else if (ElemPerCont == 2) {
      switch (PosInCont) {
      case 0:
        _andi(TReg1, Src1R, 0xffff); // Clear upper 16-bits of source
        _srl(TReg2, SrcE, 16);
        _sll(TReg3, TReg2, 16); // Clear lower 16-bits of element
        _or(TDReg, TReg1, TReg3);
        _mov(DstE, TDReg);
        break;
      case 1:
        _sll(TReg1, Src1R, 16); // Clear lower 16-bits  of source
        _sll(TReg2, SrcE, 16);
        _srl(TReg3, TReg2, 16); // Clear upper 16-bits of element
        _or(TDReg, TReg1, TReg3);
        _mov(DstE, TDReg);
        break;
      default:
        llvm::report_fatal_error("InsertElement: Invalid PosInCont");
        break;
      }
    } else if (ElemPerCont == 4) {
      switch (PosInCont) {
      case 0:
        _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source
        _srl(TReg2, SrcE, 8);
        _sll(TReg3, TReg2, 8); // Clear bits[7:0] of element
        _or(TDReg, TReg1, TReg3);
        _mov(DstE, TDReg);
        break;
      case 1:
        _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source
        _sll(TReg5, TReg1, 8);     // Position in the destination
        _lui(TReg2, Ctx->getConstantInt32(0xffff));
        _ori(TReg3, TReg2, 0x00ff);
        _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element
        _or(TDReg, TReg5, TReg4);
        _mov(DstE, TDReg);
        break;
      case 2:
        _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source
        _sll(TReg5, TReg1, 16);    // Position in the destination
        _lui(TReg2, Ctx->getConstantInt32(0xff00));
        _ori(TReg3, TReg2, 0xffff);
        _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element
        _or(TDReg, TReg5, TReg4);
        _mov(DstE, TDReg);
        break;
      case 3:
        _srl(TReg1, Src1R, 24); // Position in the destination
        _sll(TReg2, SrcE, 8);
        _srl(TReg3, TReg2, 8); // Clear bits[31:24] of element
        _or(TDReg, TReg1, TReg3);
        _mov(DstE, TDReg);
        break;
      default:
        llvm::report_fatal_error("InsertElement: Invalid PosInCont");
        break;
      }
    }
    // Write back temporary vector to the destination
    auto *Assign = InstAssign::create(Func, Dest, TDest);
    lowerAssign(Assign);
    return;
  }
  llvm::report_fatal_error("InsertElement requires a constant index");
}

void TargetMIPS32::createArithInst(Intrinsics::AtomicRMWOperation Operation,
                                   Variable *Dest, Variable *Src0,
                                   Variable *Src1) {
  switch (Operation) {
  default:
    llvm::report_fatal_error("Unknown AtomicRMW operation");
  case Intrinsics::AtomicExchange:
    llvm::report_fatal_error("Can't handle Atomic xchg operation");
  case Intrinsics::AtomicAdd:
    _addu(Dest, Src0, Src1);
    break;
  case Intrinsics::AtomicAnd:
    _and(Dest, Src0, Src1);
    break;
  case Intrinsics::AtomicSub:
    _subu(Dest, Src0, Src1);
    break;
  case Intrinsics::AtomicOr:
    _or(Dest, Src0, Src1);
    break;
  case Intrinsics::AtomicXor:
    _xor(Dest, Src0, Src1);
    break;
  }
}

void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
  Variable *Dest = Instr->getDest();
  Type DestTy = (Dest == nullptr) ? IceType_void : Dest->getType();

  Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID;
  switch (ID) {
  case Intrinsics::AtomicLoad: {
    assert(isScalarIntegerType(DestTy));
    // We require the memory address to be naturally aligned. Given that is the
    // case, then normal loads are atomic.
    if (!Intrinsics::isMemoryOrderValid(
            ID, getConstantMemoryOrder(Instr->getArg(1)))) {
      Func->setError("Unexpected memory ordering for AtomicLoad");
      return;
    }
    if (DestTy == IceType_i64) {
      auto *Base = legalizeToReg(Instr->getArg(0));
      auto *AddrLo = OperandMIPS32Mem::create(
          Func, IceType_i32, Base,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0)));
      auto *AddrHi = OperandMIPS32Mem::create(
          Func, IceType_i32, Base,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
      auto *T_Lo = makeReg(IceType_i32);
      auto *T_Hi = makeReg(IceType_i32);
      auto *Dest64 = llvm::cast<Variable64On32>(Dest);
      lowerLoad(InstLoad::create(Func, T_Lo, AddrLo, IceType_i32));
      lowerLoad(InstLoad::create(Func, T_Hi, AddrHi, IceType_i32));
      _sync();
      _mov(Dest64->getLo(), T_Lo);
      _mov(Dest64->getHi(), T_Hi);
      // Adding a fake-use of T to ensure the atomic load is not removed if Dest
      // is unused.
      Context.insert<InstFakeUse>(T_Lo);
      Context.insert<InstFakeUse>(T_Hi);
    } else {
      auto *T = makeReg(DestTy);
      lowerLoad(InstLoad::create(Func, T,
                                 formMemoryOperand(Instr->getArg(0), DestTy)));
      _sync();
      _mov(Dest, T);
      // Adding a fake-use of T to ensure the atomic load is not removed if Dest
      // is unused.
      Context.insert<InstFakeUse>(T);
    }
    return;
  }
  case Intrinsics::AtomicStore: {
    // We require the memory address to be naturally aligned. Given that is the
    // case, then normal stores are atomic.
    if (!Intrinsics::isMemoryOrderValid(
            ID, getConstantMemoryOrder(Instr->getArg(2)))) {
      Func->setError("Unexpected memory ordering for AtomicStore");
      return;
    }
    auto *Val = Instr->getArg(0);
    auto Ty = Val->getType();
    if (Ty == IceType_i64) {
      Variable *ValHi, *ValLo;
      _sync();
      if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Val)) {
        const uint64_t Value = C64->getValue();
        uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF;
        uint64_t Lower32Bits = Value & 0xFFFFFFFF;
        ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits));
        ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits));
      } else {
        auto *Val64 = llvm::cast<Variable64On32>(Val);
        ValLo = legalizeToReg(loOperand(Val64));
        ValHi = legalizeToReg(hiOperand(Val64));
      }

      auto *Base = legalizeToReg(Instr->getArg(1));
      auto *AddrLo = OperandMIPS32Mem::create(
          Func, IceType_i32, Base,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0)));
      auto *AddrHi = OperandMIPS32Mem::create(
          Func, IceType_i32, Base,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
      lowerStore(InstStore::create(Func, ValLo, AddrLo, IceType_i32));
      lowerStore(InstStore::create(Func, ValHi, AddrHi, IceType_i32));
      _sync();
    } else {
      _sync();
      auto *Val = legalizeToReg(Instr->getArg(0));
      lowerStore(InstStore::create(
          Func, Val, formMemoryOperand(Instr->getArg(1), DestTy)));
      _sync();
    }
    return;
  }
  case Intrinsics::AtomicCmpxchg: {
    assert(isScalarIntegerType(DestTy));
    // We require the memory address to be naturally aligned. Given that is the
    // case, then normal loads are atomic.
    if (!Intrinsics::isMemoryOrderValid(
            ID, getConstantMemoryOrder(Instr->getArg(3)),
            getConstantMemoryOrder(Instr->getArg(4)))) {
      Func->setError("Unexpected memory ordering for AtomicCmpxchg");
      return;
    }

    InstMIPS32Label *Exit = InstMIPS32Label::create(Func, this);
    InstMIPS32Label *Retry = InstMIPS32Label::create(Func, this);
    constexpr CfgNode *NoTarget = nullptr;
    auto *New = Instr->getArg(2);
    auto *Expected = Instr->getArg(1);
    auto *ActualAddress = Instr->getArg(0);

    if (DestTy == IceType_i64) {
      InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this);
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      _sync();
      Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi;
      if (llvm::isa<ConstantUndef>(Expected)) {
        ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32));
        ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32));
      } else {
        auto *Expected64 = llvm::cast<Variable64On32>(Expected);
        ExpectedLo = legalizeToReg(loOperand(Expected64));
        ExpectedHi = legalizeToReg(hiOperand(Expected64));
      }
      if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(New)) {
        const uint64_t Value = C64->getValue();
        uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF;
        uint64_t Lower32Bits = Value & 0xFFFFFFFF;
        ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits));
        ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits));
      } else {
        auto *Val = llvm::cast<Variable64On32>(New);
        ValLo = legalizeToReg(loOperand(Val));
        ValHi = legalizeToReg(hiOperand(Val));
      }
      auto *Dest64 = llvm::cast<Variable64On32>(Dest);
      auto *BaseR = legalizeToReg(ActualAddress);
      auto *AddrLo = OperandMIPS32Mem::create(
          Func, IceType_i32, BaseR,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0)));
      auto *AddrHi = OperandMIPS32Mem::create(
          Func, IceType_i32, BaseR,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
      Context.insert(Retry);
      _ll(T1, AddrLo);
      _br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE);
      _sc(ValLo, AddrLo);
      _br(NoTarget, NoTarget, ValLo, getZero(), Retry, CondMIPS32::Cond::EQ);
      _mov(Dest64->getLo(), T1);
      Context.insert(Retry1);
      _ll(T2, AddrHi);
      _br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE);
      _sc(ValHi, AddrHi);
      _br(NoTarget, NoTarget, ValHi, getZero(), Retry1, CondMIPS32::Cond::EQ);
      _mov(Dest64->getHi(), T2);
      Context.insert<InstFakeUse>(getZero());
      Context.insert(Exit);
      _sync();
    } else if (DestTy == IceType_i8 || DestTy == IceType_i16) {
      auto *NewR = legalizeToReg(New);
      auto *ExpectedR = legalizeToReg(Expected);
      auto *ActualAddressR = legalizeToReg(ActualAddress);
      const uint32_t ShiftAmount =
          (INT32_BITS - CHAR_BITS * typeWidthInBytes(DestTy));
      const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1;
      auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT);
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *T5 = I32Reg();
      auto *T6 = I32Reg();
      auto *T7 = I32Reg();
      auto *T8 = I32Reg();
      auto *T9 = I32Reg();
      _sync();
      _addiu(RegAt, getZero(), -4);
      _and(T1, ActualAddressR, RegAt);
      _andi(RegAt, ActualAddressR, 3);
      _sll(T2, RegAt, 3);
      _ori(RegAt, getZero(), Mask);
      _sllv(T3, RegAt, T2);
      _nor(T4, getZero(), T3);
      _andi(RegAt, ExpectedR, Mask);
      _sllv(T5, RegAt, T2);
      _andi(RegAt, NewR, Mask);
      _sllv(T6, RegAt, T2);
      Context.insert(Retry);
      _ll(T7, formMemoryOperand(T1, DestTy));
      _and(T8, T7, T3);
      _br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE);
      _and(RegAt, T7, T4);
      _or(T9, RegAt, T6);
      _sc(T9, formMemoryOperand(T1, DestTy));
      _br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      Context.insert(Exit);
      _srlv(RegAt, T8, T2);
      _sll(RegAt, RegAt, ShiftAmount);
      _sra(RegAt, RegAt, ShiftAmount);
      _mov(Dest, RegAt);
      _sync();
      Context.insert<InstFakeUse>(ExpectedR);
      Context.insert<InstFakeUse>(NewR);
    } else {
      auto *T1 = I32Reg();
      auto *NewR = legalizeToReg(New);
      auto *ExpectedR = legalizeToReg(Expected);
      auto *ActualAddressR = legalizeToReg(ActualAddress);
      _sync();
      Context.insert(Retry);
      _ll(T1, formMemoryOperand(ActualAddressR, DestTy));
      _br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE);
      _sc(NewR, formMemoryOperand(ActualAddressR, DestTy));
      _br(NoTarget, NoTarget, NewR, getZero(), Retry, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      Context.insert(Exit);
      _mov(Dest, T1);
      _sync();
      Context.insert<InstFakeUse>(ExpectedR);
      Context.insert<InstFakeUse>(NewR);
    }
    return;
  }
  case Intrinsics::AtomicRMW: {
    assert(isScalarIntegerType(DestTy));
    // We require the memory address to be naturally aligned. Given that is the
    // case, then normal loads are atomic.
    if (!Intrinsics::isMemoryOrderValid(
            ID, getConstantMemoryOrder(Instr->getArg(3)))) {
      Func->setError("Unexpected memory ordering for AtomicRMW");
      return;
    }

    constexpr CfgNode *NoTarget = nullptr;
    InstMIPS32Label *Retry = InstMIPS32Label::create(Func, this);
    auto Operation = static_cast<Intrinsics::AtomicRMWOperation>(
        llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue());
    auto *New = Instr->getArg(2);
    auto *ActualAddress = Instr->getArg(1);

    if (DestTy == IceType_i64) {
      InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this);
      _sync();
      Variable *ValHi, *ValLo;
      if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(New)) {
        const uint64_t Value = C64->getValue();
        uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF;
        uint64_t Lower32Bits = Value & 0xFFFFFFFF;
        ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits));
        ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits));
      } else {
        auto *Val = llvm::cast<Variable64On32>(New);
        ValLo = legalizeToReg(loOperand(Val));
        ValHi = legalizeToReg(hiOperand(Val));
      }
      auto *Dest64 = llvm::cast<Variable64On32>(Dest);
      auto *BaseR = legalizeToReg(ActualAddress);
      auto *AddrLo = OperandMIPS32Mem::create(
          Func, IceType_i32, BaseR,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0)));
      auto *AddrHi = OperandMIPS32Mem::create(
          Func, IceType_i32, BaseR,
          llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
      auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT);
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      Context.insert(Retry);
      _ll(T1, AddrLo);
      if (Operation == Intrinsics::AtomicExchange) {
        _mov(RegAt, ValLo);
      } else if (Operation == Intrinsics::AtomicAdd) {
        createArithInst(Operation, RegAt, T1, ValLo);
        _sltu(T2, RegAt, T1);
      } else if (Operation == Intrinsics::AtomicSub) {
        createArithInst(Operation, RegAt, T1, ValLo);
        _sltu(T2, T1, ValLo);
      } else {
        createArithInst(Operation, RegAt, T1, ValLo);
      }
      _sc(RegAt, AddrLo);
      _br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      _mov(Dest64->getLo(), T1);
      Context.insert(Retry1);
      _ll(T3, AddrHi);
      if (Operation == Intrinsics::AtomicAdd ||
          Operation == Intrinsics::AtomicSub) {
        _addu(RegAt, T2, ValHi);
        createArithInst(Operation, RegAt, T3, RegAt);
      } else if (Operation == Intrinsics::AtomicExchange) {
        _mov(RegAt, ValHi);
      } else {
        createArithInst(Operation, RegAt, T3, ValHi);
      }
      _sc(RegAt, AddrHi);
      _br(NoTarget, NoTarget, RegAt, getZero(), Retry1, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      _mov(Dest64->getHi(), T3);
      Context.insert<InstFakeUse>(ValLo);
      Context.insert<InstFakeUse>(ValHi);
      _sync();
    } else if (DestTy == IceType_i8 || DestTy == IceType_i16) {
      const uint32_t ShiftAmount =
          INT32_BITS - (CHAR_BITS * typeWidthInBytes(DestTy));
      const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1;
      auto *NewR = legalizeToReg(New);
      auto *ActualAddressR = legalizeToReg(ActualAddress);
      auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT);
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *T5 = I32Reg();
      auto *T6 = I32Reg();
      auto *T7 = I32Reg();
      _sync();
      _addiu(RegAt, getZero(), -4);
      _and(T1, ActualAddressR, RegAt);
      _andi(RegAt, ActualAddressR, 3);
      _sll(T2, RegAt, 3);
      _ori(RegAt, getZero(), Mask);
      _sllv(T3, RegAt, T2);
      _nor(T4, getZero(), T3);
      _sllv(T5, NewR, T2);
      Context.insert(Retry);
      _ll(T6, formMemoryOperand(T1, DestTy));
      if (Operation != Intrinsics::AtomicExchange) {
        createArithInst(Operation, RegAt, T6, T5);
        _and(RegAt, RegAt, T3);
      }
      _and(T7, T6, T4);
      if (Operation == Intrinsics::AtomicExchange) {
        _or(RegAt, T7, T5);
      } else {
        _or(RegAt, T7, RegAt);
      }
      _sc(RegAt, formMemoryOperand(T1, DestTy));
      _br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      _and(RegAt, T6, T3);
      _srlv(RegAt, RegAt, T2);
      _sll(RegAt, RegAt, ShiftAmount);
      _sra(RegAt, RegAt, ShiftAmount);
      _mov(Dest, RegAt);
      _sync();
      Context.insert<InstFakeUse>(NewR);
      Context.insert<InstFakeUse>(Dest);
    } else {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *NewR = legalizeToReg(New);
      auto *ActualAddressR = legalizeToReg(ActualAddress);
      _sync();
      Context.insert(Retry);
      _ll(T1, formMemoryOperand(ActualAddressR, DestTy));
      if (Operation == Intrinsics::AtomicExchange) {
        _mov(T2, NewR);
      } else {
        createArithInst(Operation, T2, T1, NewR);
      }
      _sc(T2, formMemoryOperand(ActualAddressR, DestTy));
      _br(NoTarget, NoTarget, T2, getZero(), Retry, CondMIPS32::Cond::EQ);
      Context.insert<InstFakeUse>(getZero());
      _mov(Dest, T1);
      _sync();
      Context.insert<InstFakeUse>(NewR);
      Context.insert<InstFakeUse>(Dest);
    }
    return;
  }
  case Intrinsics::AtomicFence:
  case Intrinsics::AtomicFenceAll:
    assert(Dest == nullptr);
    _sync();
    return;
  case Intrinsics::AtomicIsLockFree: {
    Operand *ByteSize = Instr->getArg(0);
    auto *CI = llvm::dyn_cast<ConstantInteger32>(ByteSize);
    auto *T = I32Reg();
    if (CI == nullptr) {
      // The PNaCl ABI requires the byte size to be a compile-time constant.
      Func->setError("AtomicIsLockFree byte size should be compile-time const");
      return;
    }
    static constexpr int32_t NotLockFree = 0;
    static constexpr int32_t LockFree = 1;
    int32_t Result = NotLockFree;
    switch (CI->getValue()) {
    case 1:
    case 2:
    case 4:
    case 8:
      Result = LockFree;
      break;
    }
    _addiu(T, getZero(), Result);
    _mov(Dest, T);
    return;
  }
  case Intrinsics::Bswap: {
    auto *Src = Instr->getArg(0);
    const Type SrcTy = Src->getType();
    assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 ||
           SrcTy == IceType_i64);
    switch (SrcTy) {
    case IceType_i16: {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *SrcR = legalizeToReg(Src);
      _sll(T1, SrcR, 8);
      _lui(T2, Ctx->getConstantInt32(255));
      _and(T1, T1, T2);
      _sll(T3, SrcR, 24);
      _or(T1, T3, T1);
      _srl(T4, T1, 16);
      _mov(Dest, T4);
      return;
    }
    case IceType_i32: {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *T5 = I32Reg();
      auto *SrcR = legalizeToReg(Src);
      _srl(T1, SrcR, 24);
      _srl(T2, SrcR, 8);
      _andi(T2, T2, 0xFF00);
      _or(T1, T2, T1);
      _sll(T4, SrcR, 8);
      _lui(T3, Ctx->getConstantInt32(255));
      _and(T4, T4, T3);
      _sll(T5, SrcR, 24);
      _or(T4, T5, T4);
      _or(T4, T4, T1);
      _mov(Dest, T4);
      return;
    }
    case IceType_i64: {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *T5 = I32Reg();
      auto *T6 = I32Reg();
      auto *T7 = I32Reg();
      auto *T8 = I32Reg();
      auto *T9 = I32Reg();
      auto *T10 = I32Reg();
      auto *T11 = I32Reg();
      auto *T12 = I32Reg();
      auto *T13 = I32Reg();
      auto *T14 = I32Reg();
      auto *T15 = I32Reg();
      auto *T16 = I32Reg();
      auto *T17 = I32Reg();
      auto *T18 = I32Reg();
      auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
      auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
      Src = legalizeUndef(Src);
      auto *SrcLoR = legalizeToReg(loOperand(Src));
      auto *SrcHiR = legalizeToReg(hiOperand(Src));
      _sll(T1, SrcHiR, 8);
      _srl(T2, SrcHiR, 24);
      _srl(T3, SrcHiR, 8);
      _andi(T3, T3, 0xFF00);
      _lui(T4, Ctx->getConstantInt32(255));
      _or(T5, T3, T2);
      _and(T6, T1, T4);
      _sll(T7, SrcHiR, 24);
      _or(T8, T7, T6);
      _srl(T9, SrcLoR, 24);
      _srl(T10, SrcLoR, 8);
      _andi(T11, T10, 0xFF00);
      _or(T12, T8, T5);
      _or(T13, T11, T9);
      _sll(T14, SrcLoR, 8);
      _and(T15, T14, T4);
      _sll(T16, SrcLoR, 24);
      _or(T17, T16, T15);
      _or(T18, T17, T13);
      _mov(DestLo, T12);
      _mov(DestHi, T18);
      return;
    }
    default:
      llvm::report_fatal_error("Control flow should never have reached here.");
    }
    return;
  }
  case Intrinsics::Ctpop: {
    llvm::report_fatal_error("Ctpop should have been prelowered.");
    return;
  }
  case Intrinsics::Ctlz: {
    auto *Src = Instr->getArg(0);
    const Type SrcTy = Src->getType();
    assert(SrcTy == IceType_i32 || SrcTy == IceType_i64);
    switch (SrcTy) {
    case IceType_i32: {
      auto *T = I32Reg();
      auto *SrcR = legalizeToReg(Src);
      _clz(T, SrcR);
      _mov(Dest, T);
      break;
    }
    case IceType_i64: {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
      auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
      Variable *SrcHiR = legalizeToReg(hiOperand(Src));
      Variable *SrcLoR = legalizeToReg(loOperand(Src));
      _clz(T1, SrcHiR);
      _clz(T2, SrcLoR);
      _addiu(T3, T2, 32);
      _movn(T3, T1, SrcHiR);
      _addiu(T4, getZero(), 0);
      _mov(DestHi, T4);
      _mov(DestLo, T3);
      break;
    }
    default:
      llvm::report_fatal_error("Control flow should never have reached here.");
    }
    break;
  }
  case Intrinsics::Cttz: {
    auto *Src = Instr->getArg(0);
    const Type SrcTy = Src->getType();
    assert(SrcTy == IceType_i32 || SrcTy == IceType_i64);
    switch (SrcTy) {
    case IceType_i32: {
      auto *T1 = I32Reg();
      auto *T2 = I32Reg();
      auto *T3 = I32Reg();
      auto *T4 = I32Reg();
      auto *T5 = I32Reg();
      auto *T6 = I32Reg();
      auto *SrcR = legalizeToReg(Src);
      _addiu(T1, SrcR, -1);
      _not(T2, SrcR);
      _and(T3, T2, T1);
      _clz(T4, T3);
      _addiu(T5, getZero(), 32);
      _subu(T6, T5, T4);
      _mov(Dest, T6);
      break;
    }
    case IceType_i64: {
      auto *THi1 = I32Reg();
      auto *THi2 = I32Reg();
      auto *THi3 = I32Reg();
      auto *THi4 = I32Reg();
      auto *THi5 = I32Reg();
      auto *THi6 = I32Reg();
      auto *TLo1 = I32Reg();
      auto *TLo2 = I32Reg();
      auto *TLo3 = I32Reg();
      auto *TLo4 = I32Reg();
      auto *TLo5 = I32Reg();
      auto *TLo6 = I32Reg();
      auto *TResHi = I32Reg();
      auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
      auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
      Variable *SrcHiR = legalizeToReg(hiOperand(Src));
      Variable *SrcLoR = legalizeToReg(loOperand(Src));
      _addiu(THi1, SrcHiR, -1);
      _not(THi2, SrcHiR);
      _and(THi3, THi2, THi1);
      _clz(THi4, THi3);
      _addiu(THi5, getZero(), 64);
      _subu(THi6, THi5, THi4);
      _addiu(TLo1, SrcLoR, -1);
      _not(TLo2, SrcLoR);
      _and(TLo3, TLo2, TLo1);
      _clz(TLo4, TLo3);
      _addiu(TLo5, getZero(), 32);
      _subu(TLo6, TLo5, TLo4);
      _movn(THi6, TLo6, SrcLoR);
      _addiu(TResHi, getZero(), 0);
      _mov(DestHi, TResHi);
      _mov(DestLo, THi6);
      break;
    }
    default:
      llvm::report_fatal_error("Control flow should never have reached here.");
    }
    return;
  }
  case Intrinsics::Fabs: {
    if (isScalarFloatingType(DestTy)) {
      Variable *T = makeReg(DestTy);
      if (DestTy == IceType_f32) {
        _abs_s(T, legalizeToReg(Instr->getArg(0)));
      } else {
        _abs_d(T, legalizeToReg(Instr->getArg(0)));
      }
      _mov(Dest, T);
    }
    return;
  }
  case Intrinsics::Longjmp: {
    llvm::report_fatal_error("longjmp should have been prelowered.");
    return;
  }
  case Intrinsics::Memcpy: {
    llvm::report_fatal_error("memcpy should have been prelowered.");
    return;
  }
  case Intrinsics::Memmove: {
    llvm::report_fatal_error("memmove should have been prelowered.");
    return;
  }
  case Intrinsics::Memset: {
    llvm::report_fatal_error("memset should have been prelowered.");
    return;
  }
  case Intrinsics::NaClReadTP: {
    if (getFlags().getUseSandboxing()) {
      UnimplementedLoweringError(this, Instr);
    } else {
      InstCall *Call =
          makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0);
      lowerCall(Call);
    }
    return;
  }
  case Intrinsics::Setjmp: {
    llvm::report_fatal_error("setjmp should have been prelowered.");
    return;
  }
  case Intrinsics::Sqrt: {
    if (isScalarFloatingType(DestTy)) {
      Variable *T = makeReg(DestTy);
      if (DestTy == IceType_f32) {
        _sqrt_s(T, legalizeToReg(Instr->getArg(0)));
      } else {
        _sqrt_d(T, legalizeToReg(Instr->getArg(0)));
      }
      _mov(Dest, T);
    } else {
      assert(getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl);
      UnimplementedLoweringError(this, Instr); // Not required for PNaCl
    }
    return;
  }
  case Intrinsics::Stacksave: {
    Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
    _mov(Dest, SP);
    return;
  }
  case Intrinsics::Stackrestore: {
    Variable *Val = legalizeToReg(Instr->getArg(0));
    Sandboxer(this).reset_sp(Val);
    return;
  }
  case Intrinsics::Trap: {
    const uint32_t TrapCodeZero = 0;
    _teq(getZero(), getZero(), TrapCodeZero);
    return;
  }
  case Intrinsics::LoadSubVector: {
    UnimplementedLoweringError(this, Instr); // Not required for PNaCl
    return;
  }
  case Intrinsics::StoreSubVector: {
    UnimplementedLoweringError(this, Instr); // Not required for PNaCl
    return;
  }
  default: // UnknownIntrinsic
    Func->setError("Unexpected intrinsic");
    return;
  }
  return;
}

void TargetMIPS32::lowerLoad(const InstLoad *Instr) {
  // A Load instruction can be treated the same as an Assign instruction, after
  // the source operand is transformed into an OperandMIPS32Mem operand.
  Type Ty = Instr->getDest()->getType();
  Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty);
  Variable *DestLoad = Instr->getDest();
  auto *Assign = InstAssign::create(Func, DestLoad, Src0);
  lowerAssign(Assign);
}

namespace {
void dumpAddressOpt(const Cfg *Func, const Variable *Base, int32_t Offset,
                    const Inst *Reason) {
  if (!BuildDefs::dump())
    return;
  if (!Func->isVerbose(IceV_AddrOpt))
    return;
  OstreamLocker _(Func->getContext());
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "Instruction: ";
  Reason->dumpDecorated(Func);
  Str << "  results in Base=";
  if (Base)
    Base->dump(Func);
  else
    Str << "<null>";
  Str << ", Offset=" << Offset << "\n";
}

bool matchAssign(const VariablesMetadata *VMetadata, Variable **Var,
                 int32_t *Offset, const Inst **Reason) {
  // Var originates from Var=SrcVar ==> set Var:=SrcVar
  if (*Var == nullptr)
    return false;
  const Inst *VarAssign = VMetadata->getSingleDefinition(*Var);
  if (!VarAssign)
    return false;
  assert(!VMetadata->isMultiDef(*Var));
  if (!llvm::isa<InstAssign>(VarAssign))
    return false;

  Operand *SrcOp = VarAssign->getSrc(0);
  bool Optimized = false;
  if (auto *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
    if (!VMetadata->isMultiDef(SrcVar) ||
        // TODO: ensure SrcVar stays single-BB
        false) {
      Optimized = true;
      *Var = SrcVar;
    } else if (auto *Const = llvm::dyn_cast<ConstantInteger32>(SrcOp)) {
      int32_t MoreOffset = Const->getValue();
      int32_t NewOffset = MoreOffset + *Offset;
      if (Utils::WouldOverflowAdd(*Offset, MoreOffset))
        return false;
      *Var = nullptr;
      *Offset += NewOffset;
      Optimized = true;
    }
  }

  if (Optimized) {
    *Reason = VarAssign;
  }

  return Optimized;
}

bool isAddOrSub(const Inst *Instr, InstArithmetic::OpKind *Kind) {
  if (const auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) {
    switch (Arith->getOp()) {
    default:
      return false;
    case InstArithmetic::Add:
    case InstArithmetic::Sub:
      *Kind = Arith->getOp();
      return true;
    }
  }
  return false;
}

bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable **Base,
                     int32_t *Offset, const Inst **Reason) {
  // Base is Base=Var+Const || Base is Base=Const+Var ==>
  //   set Base=Var, Offset+=Const
  // Base is Base=Var-Const ==>
  //   set Base=Var, Offset-=Const
  if (*Base == nullptr)
    return false;
  const Inst *BaseInst = VMetadata->getSingleDefinition(*Base);
  if (BaseInst == nullptr) {
    return false;
  }
  assert(!VMetadata->isMultiDef(*Base));

  auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(BaseInst);
  if (ArithInst == nullptr)
    return false;
  InstArithmetic::OpKind Kind;
  if (!isAddOrSub(ArithInst, &Kind))
    return false;
  bool IsAdd = Kind == InstArithmetic::Add;
  Operand *Src0 = ArithInst->getSrc(0);
  Operand *Src1 = ArithInst->getSrc(1);
  auto *Var0 = llvm::dyn_cast<Variable>(Src0);
  auto *Var1 = llvm::dyn_cast<Variable>(Src1);
  auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0);
  auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1);
  Variable *NewBase = nullptr;
  int32_t NewOffset = *Offset;

  if (Var0 == nullptr && Const0 == nullptr) {
    assert(llvm::isa<ConstantRelocatable>(Src0));
    return false;
  }

  if (Var1 == nullptr && Const1 == nullptr) {
    assert(llvm::isa<ConstantRelocatable>(Src1));
    return false;
  }

  if (Var0 && Var1)
    // TODO(jpp): merge base/index splitting into here.
    return false;
  if (!IsAdd && Var1)
    return false;
  if (Var0)
    NewBase = Var0;
  else if (Var1)
    NewBase = Var1;
  // Compute the updated constant offset.
  if (Const0) {
    int32_t MoreOffset = IsAdd ? Const0->getValue() : -Const0->getValue();
    if (Utils::WouldOverflowAdd(NewOffset, MoreOffset))
      return false;
    NewOffset += MoreOffset;
  }
  if (Const1) {
    int32_t MoreOffset = IsAdd ? Const1->getValue() : -Const1->getValue();
    if (Utils::WouldOverflowAdd(NewOffset, MoreOffset))
      return false;
    NewOffset += MoreOffset;
  }

  // Update the computed address parameters once we are sure optimization
  // is valid.
  *Base = NewBase;
  *Offset = NewOffset;
  *Reason = BaseInst;
  return true;
}
} // end of anonymous namespace

OperandMIPS32Mem *TargetMIPS32::formAddressingMode(Type Ty, Cfg *Func,
                                                   const Inst *LdSt,
                                                   Operand *Base) {
  assert(Base != nullptr);
  int32_t OffsetImm = 0;

  Func->resetCurrentNode();
  if (Func->isVerbose(IceV_AddrOpt)) {
    OstreamLocker _(Func->getContext());
    Ostream &Str = Func->getContext()->getStrDump();
    Str << "\nAddress mode formation:\t";
    LdSt->dumpDecorated(Func);
  }

  if (isVectorType(Ty)) {
    return nullptr;
  }

  auto *BaseVar = llvm::dyn_cast<Variable>(Base);
  if (BaseVar == nullptr)
    return nullptr;

  const VariablesMetadata *VMetadata = Func->getVMetadata();
  const Inst *Reason = nullptr;

  do {
    if (Reason != nullptr) {
      dumpAddressOpt(Func, BaseVar, OffsetImm, Reason);
      Reason = nullptr;
    }

    if (matchAssign(VMetadata, &BaseVar, &OffsetImm, &Reason)) {
      continue;
    }

    if (matchOffsetBase(VMetadata, &BaseVar, &OffsetImm, &Reason)) {
      continue;
    }
  } while (Reason);

  if (BaseVar == nullptr) {
    // We need base register rather than just OffsetImm. Move the OffsetImm to
    // BaseVar and form 0(BaseVar) addressing.
    const Type PointerType = getPointerType();
    BaseVar = makeReg(PointerType);
    Context.insert<InstAssign>(BaseVar, Ctx->getConstantInt32(OffsetImm));
    OffsetImm = 0;
  } else if (OffsetImm != 0) {
    // If the OffsetImm is more than signed 16-bit value then add it in the
    // BaseVar and form 0(BaseVar) addressing.
    const int32_t PositiveOffset = OffsetImm > 0 ? OffsetImm : -OffsetImm;
    const InstArithmetic::OpKind Op =
        OffsetImm > 0 ? InstArithmetic::Add : InstArithmetic::Sub;
    constexpr bool ZeroExt = false;
    if (!OperandMIPS32Mem::canHoldOffset(Ty, ZeroExt, OffsetImm)) {
      const Type PointerType = getPointerType();
      Variable *T = makeReg(PointerType);
      Context.insert<InstArithmetic>(Op, T, BaseVar,
                                     Ctx->getConstantInt32(PositiveOffset));
      BaseVar = T;
      OffsetImm = 0;
    }
  }

  assert(BaseVar != nullptr);
  assert(OffsetImm < 0 ? (-OffsetImm & 0x0000ffff) == -OffsetImm
                       : (OffsetImm & 0x0000ffff) == OffsetImm);

  return OperandMIPS32Mem::create(
      Func, Ty, BaseVar,
      llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(OffsetImm)));
}

void TargetMIPS32::doAddressOptLoad() {
  Inst *Instr = iteratorToInst(Context.getCur());
  assert(llvm::isa<InstLoad>(Instr));
  Variable *Dest = Instr->getDest();
  Operand *Addr = Instr->getSrc(0);
  if (OperandMIPS32Mem *Mem =
          formAddressingMode(Dest->getType(), Func, Instr, Addr)) {
    Instr->setDeleted();
    Context.insert<InstLoad>(Dest, Mem);
  }
}

void TargetMIPS32::randomlyInsertNop(float Probability,
                                     RandomNumberGenerator &RNG) {
  RandomNumberGeneratorWrapper RNGW(RNG);
  if (RNGW.getTrueWithProbability(Probability)) {
    _nop();
  }
}

void TargetMIPS32::lowerPhi(const InstPhi * /*Instr*/) {
  Func->setError("Phi found in regular instruction list");
}

void TargetMIPS32::lowerRet(const InstRet *Instr) {
  Variable *Reg = nullptr;
  if (Instr->hasRetValue()) {
    Operand *Src0 = Instr->getRetValue();
    switch (Src0->getType()) {
    case IceType_f32: {
      Operand *Src0F = legalizeToReg(Src0);
      Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0);
      _mov(Reg, Src0F);
      break;
    }
    case IceType_f64: {
      Operand *Src0F = legalizeToReg(Src0);
      Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0F1);
      _mov(Reg, Src0F);
      break;
    }
    case IceType_i1:
    case IceType_i8:
    case IceType_i16:
    case IceType_i32: {
      Operand *Src0F = legalizeToReg(Src0);
      Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
      _mov(Reg, Src0F);
      break;
    }
    case IceType_i64: {
      Src0 = legalizeUndef(Src0);
      Variable *R0 = legalizeToReg(loOperand(Src0), RegMIPS32::Reg_V0);
      Variable *R1 = legalizeToReg(hiOperand(Src0), RegMIPS32::Reg_V1);
      Reg = R0;
      Context.insert<InstFakeUse>(R1);
      break;
    }
    case IceType_v4i1:
    case IceType_v8i1:
    case IceType_v16i1:
    case IceType_v16i8:
    case IceType_v8i16:
    case IceType_v4i32: {
      auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(legalizeUndef(Src0));
      Variable *V0 =
          legalizeToReg(SrcVec->getContainers()[0], RegMIPS32::Reg_V0);
      Variable *V1 =
          legalizeToReg(SrcVec->getContainers()[1], RegMIPS32::Reg_V1);
      Variable *A0 =
          legalizeToReg(SrcVec->getContainers()[2], RegMIPS32::Reg_A0);
      Variable *A1 =
          legalizeToReg(SrcVec->getContainers()[3], RegMIPS32::Reg_A1);
      Reg = V0;
      Context.insert<InstFakeUse>(V1);
      Context.insert<InstFakeUse>(A0);
      Context.insert<InstFakeUse>(A1);
      break;
    }
    case IceType_v4f32: {
      auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(legalizeUndef(Src0));
      Reg = getImplicitRet();
      auto *RegT = legalizeToReg(Reg);
      // Return the vector through buffer in implicit argument a0
      for (SizeT i = 0; i < SrcVec->ContainersPerVector; ++i) {
        OperandMIPS32Mem *Mem = OperandMIPS32Mem::create(
            Func, IceType_f32, RegT,
            llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4)));
        Variable *Var = legalizeToReg(SrcVec->getContainers()[i]);
        _sw(Var, Mem);
      }
      Variable *V0 = makeReg(IceType_i32, RegMIPS32::Reg_V0);
      _mov(V0, Reg); // move v0,a0
      Context.insert<InstFakeUse>(Reg);
      Context.insert<InstFakeUse>(V0);
      break;
    }
    default:
      llvm::report_fatal_error("Ret: Invalid type.");
      break;
    }
  }
  _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg);
}

void TargetMIPS32::lowerSelect(const InstSelect *Instr) {
  Variable *Dest = Instr->getDest();
  const Type DestTy = Dest->getType();

  if (isVectorType(DestTy)) {
    llvm::report_fatal_error("Select: Destination type is vector");
    return;
  }

  Variable *DestR = nullptr;
  Variable *DestHiR = nullptr;
  Variable *SrcTR = nullptr;
  Variable *SrcTHiR = nullptr;
  Variable *SrcFR = nullptr;
  Variable *SrcFHiR = nullptr;

  if (DestTy == IceType_i64) {
    DestR = llvm::cast<Variable>(loOperand(Dest));
    DestHiR = llvm::cast<Variable>(hiOperand(Dest));
    SrcTR = legalizeToReg(loOperand(legalizeUndef(Instr->getTrueOperand())));
    SrcTHiR = legalizeToReg(hiOperand(legalizeUndef(Instr->getTrueOperand())));
    SrcFR = legalizeToReg(loOperand(legalizeUndef(Instr->getFalseOperand())));
    SrcFHiR = legalizeToReg(hiOperand(legalizeUndef(Instr->getFalseOperand())));
  } else {
    SrcTR = legalizeToReg(legalizeUndef(Instr->getTrueOperand()));
    SrcFR = legalizeToReg(legalizeUndef(Instr->getFalseOperand()));
  }

  Variable *ConditionR = legalizeToReg(Instr->getCondition());

  assert(Instr->getCondition()->getType() == IceType_i1);

  switch (DestTy) {
  case IceType_i1:
  case IceType_i8:
  case IceType_i16:
  case IceType_i32:
    _movn(SrcFR, SrcTR, ConditionR);
    _mov(Dest, SrcFR);
    break;
  case IceType_i64:
    _movn(SrcFR, SrcTR, ConditionR);
    _movn(SrcFHiR, SrcTHiR, ConditionR);
    _mov(DestR, SrcFR);
    _mov(DestHiR, SrcFHiR);
    break;
  case IceType_f32:
    _movn_s(SrcFR, SrcTR, ConditionR);
    _mov(Dest, SrcFR);
    break;
  case IceType_f64:
    _movn_d(SrcFR, SrcTR, ConditionR);
    _mov(Dest, SrcFR);
    break;
  default:
    llvm::report_fatal_error("Select: Invalid type.");
  }
}

void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) {
  UnimplementedLoweringError(this, Instr);
}

void TargetMIPS32::lowerStore(const InstStore *Instr) {
  Operand *Value = Instr->getData();
  Operand *Addr = Instr->getAddr();
  OperandMIPS32Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
  Type Ty = NewAddr->getType();

  if (Ty == IceType_i64) {
    Value = legalizeUndef(Value);
    Variable *ValueHi = legalizeToReg(hiOperand(Value));
    Variable *ValueLo = legalizeToReg(loOperand(Value));
    _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr)));
    _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr)));
  } else if (isVectorType(Value->getType())) {
    auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value);
    for (SizeT i = 0; i < DataVec->ContainersPerVector; ++i) {
      auto *DCont = legalizeToReg(DataVec->getContainers()[i]);
      auto *MCont = llvm::cast<OperandMIPS32Mem>(
          getOperandAtIndex(NewAddr, IceType_i32, i));
      _sw(DCont, MCont);
    }
  } else {
    Variable *ValueR = legalizeToReg(Value);
    _sw(ValueR, NewAddr);
  }
}

void TargetMIPS32::doAddressOptStore() {
  Inst *Instr = iteratorToInst(Context.getCur());
  assert(llvm::isa<InstStore>(Instr));
  Operand *Src = Instr->getSrc(0);
  Operand *Addr = Instr->getSrc(1);
  if (OperandMIPS32Mem *Mem =
          formAddressingMode(Src->getType(), Func, Instr, Addr)) {
    Instr->setDeleted();
    Context.insert<InstStore>(Src, Mem);
  }
}

void TargetMIPS32::lowerSwitch(const InstSwitch *Instr) {
  Operand *Src = Instr->getComparison();
  SizeT NumCases = Instr->getNumCases();
  if (Src->getType() == IceType_i64) {
    Src = legalizeUndef(Src);
    Variable *Src0Lo = legalizeToReg(loOperand(Src));
    Variable *Src0Hi = legalizeToReg(hiOperand(Src));
    for (SizeT I = 0; I < NumCases; ++I) {
      Operand *ValueLo = Ctx->getConstantInt32(Instr->getValue(I));
      Operand *ValueHi = Ctx->getConstantInt32(Instr->getValue(I) >> 32);
      CfgNode *TargetTrue = Instr->getLabel(I);
      constexpr CfgNode *NoTarget = nullptr;
      ValueHi = legalizeToReg(ValueHi);
      InstMIPS32Label *IntraLabel = InstMIPS32Label::create(Func, this);
      _br(NoTarget, NoTarget, Src0Hi, ValueHi, IntraLabel,
          CondMIPS32::Cond::NE);
      ValueLo = legalizeToReg(ValueLo);
      _br(NoTarget, TargetTrue, Src0Lo, ValueLo, CondMIPS32::Cond::EQ);
      Context.insert(IntraLabel);
    }
    _br(Instr->getLabelDefault());
    return;
  }
  Variable *SrcVar = legalizeToReg(Src);
  assert(SrcVar->mustHaveReg());
  for (SizeT I = 0; I < NumCases; ++I) {
    Operand *Value = Ctx->getConstantInt32(Instr->getValue(I));
    CfgNode *TargetTrue = Instr->getLabel(I);
    constexpr CfgNode *NoTargetFalse = nullptr;
    Value = legalizeToReg(Value);
    _br(NoTargetFalse, TargetTrue, SrcVar, Value, CondMIPS32::Cond::EQ);
  }
  _br(Instr->getLabelDefault());
}

void TargetMIPS32::lowerBreakpoint(const InstBreakpoint *Instr) {
  UnimplementedLoweringError(this, Instr);
}

void TargetMIPS32::lowerUnreachable(const InstUnreachable *) {
  const uint32_t TrapCodeZero = 0;
  _teq(getZero(), getZero(), TrapCodeZero);
}

// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
// integrity of liveness analysis. Undef values are also turned into zeroes,
// since loOperand() and hiOperand() don't expect Undef input.
void TargetMIPS32::prelowerPhis() {
  PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func);
}

void TargetMIPS32::postLower() {
  if (Func->getOptLevel() == Opt_m1)
    return;
  markRedefinitions();
  Context.availabilityUpdate();
}

void TargetMIPS32::makeRandomRegisterPermutation(
    llvm::SmallVectorImpl<RegNumT> &Permutation,
    const SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
  (void)Permutation;
  (void)ExcludeRegisters;
  (void)Salt;
  UnimplementedError(getFlags());
}

/* TODO(jvoung): avoid duplicate symbols with multiple targets.
void ConstantUndef::emitWithoutDollar(GlobalContext *) const {
  llvm_unreachable("Not expecting to emitWithoutDollar undef");
}

void ConstantUndef::emit(GlobalContext *) const {
  llvm_unreachable("undef value encountered by emitter.");
}
*/

TargetDataMIPS32::TargetDataMIPS32(GlobalContext *Ctx)
    : TargetDataLowering(Ctx) {}

// Generate .MIPS.abiflags section. This section contains a versioned data
// structure with essential information required for loader to determine the
// requirements of the application.
void TargetDataMIPS32::emitTargetRODataSections() {
  struct MipsABIFlagsSection Flags;
  ELFObjectWriter *Writer = Ctx->getObjectWriter();
  const std::string Name = ".MIPS.abiflags";
  const llvm::ELF::Elf64_Word ShType = llvm::ELF::SHT_MIPS_ABIFLAGS;
  const llvm::ELF::Elf64_Xword ShFlags = llvm::ELF::SHF_ALLOC;
  const llvm::ELF::Elf64_Xword ShAddralign = 8;
  const llvm::ELF::Elf64_Xword ShEntsize = sizeof(Flags);
  Writer->writeTargetRODataSection(
      Name, ShType, ShFlags, ShAddralign, ShEntsize,
      llvm::StringRef(reinterpret_cast<const char *>(&Flags), sizeof(Flags)));
}

void TargetDataMIPS32::lowerGlobals(const VariableDeclarationList &Vars,
                                    const std::string &SectionSuffix) {
  const bool IsPIC = getFlags().getUseNonsfi();
  switch (getFlags().getOutFileType()) {
  case FT_Elf: {
    ELFObjectWriter *Writer = Ctx->getObjectWriter();
    Writer->writeDataSection(Vars, llvm::ELF::R_MIPS_32, SectionSuffix, IsPIC);
  } break;
  case FT_Asm:
  case FT_Iasm: {
    OstreamLocker L(Ctx);
    for (const VariableDeclaration *Var : Vars) {
      if (getFlags().matchTranslateOnly(Var->getName(), 0)) {
        emitGlobal(*Var, SectionSuffix);
      }
    }
  } break;
  }
}

namespace {
template <typename T> struct ConstantPoolEmitterTraits;

static_assert(sizeof(uint64_t) == 8,
              "uint64_t is supposed to be 8 bytes wide.");

// TODO(jaydeep.patil): implement the following when implementing constant
// randomization:
//  * template <> struct ConstantPoolEmitterTraits<uint8_t>
//  * template <> struct ConstantPoolEmitterTraits<uint16_t>
//  * template <> struct ConstantPoolEmitterTraits<uint32_t>
template <> struct ConstantPoolEmitterTraits<float> {
  using ConstantType = ConstantFloat;
  static constexpr Type IceType = IceType_f32;
  // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy
  // about them being constexpr.
  static const char AsmTag[];
  static const char TypeName[];
  static uint64_t bitcastToUint64(float Value) {
    static_assert(sizeof(Value) == sizeof(uint32_t),
                  "Float should be 4 bytes.");
    const uint32_t IntValue = Utils::bitCopy<uint32_t>(Value);
    return static_cast<uint64_t>(IntValue);
  }
};
const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".word";
const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32";

template <> struct ConstantPoolEmitterTraits<double> {
  using ConstantType = ConstantDouble;
  static constexpr Type IceType = IceType_f64;
  static const char AsmTag[];
  static const char TypeName[];
  static uint64_t bitcastToUint64(double Value) {
    static_assert(sizeof(double) == sizeof(uint64_t),
                  "Double should be 8 bytes.");
    return Utils::bitCopy<uint64_t>(Value);
  }
};
const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad";
const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64";

template <typename T>
void emitConstant(
    Ostream &Str,
    const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) {
  if (!BuildDefs::dump())
    return;
  using Traits = ConstantPoolEmitterTraits<T>;
  Str << Const->getLabelName();
  T Value = Const->getValue();
  Str << ":\n\t" << Traits::AsmTag << "\t0x";
  Str.write_hex(Traits::bitcastToUint64(Value));
  Str << "\t/* " << Traits::TypeName << " " << Value << " */\n";
}

template <typename T> void emitConstantPool(GlobalContext *Ctx) {
  if (!BuildDefs::dump())
    return;
  using Traits = ConstantPoolEmitterTraits<T>;
  static constexpr size_t MinimumAlignment = 4;
  SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType));
  assert((Align % 4) == 0 && "Constants should be aligned");
  Ostream &Str = Ctx->getStrEmit();
  ConstantList Pool = Ctx->getConstantPool(Traits::IceType);
  Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align
      << "\n"
      << "\t.align\t" << (Align == 4 ? 2 : 3) << "\n";
  if (getFlags().getReorderPooledConstants()) {
    // TODO(jaydeep.patil): add constant pooling.
    UnimplementedError(getFlags());
  }
  for (Constant *C : Pool) {
    if (!C->getShouldBePooled()) {
      continue;
    }
    emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C));
  }
}
} // end of anonymous namespace

void TargetDataMIPS32::lowerConstants() {
  if (getFlags().getDisableTranslation())
    return;
  switch (getFlags().getOutFileType()) {
  case FT_Elf: {
    ELFObjectWriter *Writer = Ctx->getObjectWriter();
    Writer->writeConstantPool<ConstantFloat>(IceType_f32);
    Writer->writeConstantPool<ConstantDouble>(IceType_f64);
  } break;
  case FT_Asm:
  case FT_Iasm: {
    OstreamLocker _(Ctx);
    emitConstantPool<float>(Ctx);
    emitConstantPool<double>(Ctx);
    break;
  }
  }
}

void TargetDataMIPS32::lowerJumpTables() {
  if (getFlags().getDisableTranslation())
    return;
}

// Helper for legalize() to emit the right code to lower an operand to a
// register of the appropriate type.
Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
  Type Ty = Src->getType();
  Variable *Reg = makeReg(Ty, RegNum);
  if (isVectorType(Ty)) {
    llvm::report_fatal_error("Invalid copy from vector type.");
  } else {
    if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Src)) {
      _lw(Reg, Mem);
    } else {
      _mov(Reg, Src);
    }
  }
  return Reg;
}

Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
                                RegNumT RegNum) {
  Type Ty = From->getType();
  // Assert that a physical register is allowed.  To date, all calls
  // to legalize() allow a physical register. Legal_Flex converts
  // registers to the right type OperandMIPS32FlexReg as needed.
  assert(Allowed & Legal_Reg);

  if (RegNum.hasNoValue()) {
    if (Variable *Subst = getContext().availabilityGet(From)) {
      // At this point we know there is a potential substitution available.
      if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
          !Subst->hasReg()) {
        // At this point we know the substitution will have a register.
        if (From->getType() == Subst->getType()) {
          // At this point we know the substitution's register is compatible.
          return Subst;
        }
      }
    }
  }

  // Go through the various types of operands:
  // OperandMIPS32Mem, Constant, and Variable.
  // Given the above assertion, if type of operand is not legal
  // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
  // to a register.
  if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(From)) {
    // Base must be in a physical register.
    Variable *Base = Mem->getBase();
    ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
    Variable *RegBase = nullptr;
    assert(Base);

    RegBase = llvm::cast<Variable>(
        legalize(Base, Legal_Reg | Legal_Rematerializable));

    if (Offset != nullptr && Offset->getValue() != 0) {
      static constexpr bool ZeroExt = false;
      if (!OperandMIPS32Mem::canHoldOffset(Ty, ZeroExt, Offset->getValue())) {
        llvm::report_fatal_error("Invalid memory offset.");
      }
    }

    // Create a new operand if there was a change.
    if (Base != RegBase) {
      Mem = OperandMIPS32Mem::create(Func, Ty, RegBase, Offset,
                                     Mem->getAddrMode());
    }

    if (Allowed & Legal_Mem) {
      From = Mem;
    } else {
      Variable *Reg = makeReg(Ty, RegNum);
      _lw(Reg, Mem);
      From = Reg;
    }
    return From;
  }

  if (llvm::isa<Constant>(From)) {
    if (llvm::isa<ConstantUndef>(From)) {
      From = legalizeUndef(From, RegNum);
      if (isVectorType(Ty))
        return From;
    }
    if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
      Variable *Reg = makeReg(Ty, RegNum);
      Variable *TReg = makeReg(Ty, RegNum);
      _lui(TReg, C, RO_Hi);
      _addiu(Reg, TReg, C, RO_Lo);
      return Reg;
    } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
      const uint32_t Value = C32->getValue();
      // Use addiu if the immediate is a 16bit value. Otherwise load it
      // using a lui-ori instructions.
      Variable *Reg = makeReg(Ty, RegNum);
      if (isInt<16>(int32_t(Value))) {
        Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO);
        Context.insert<InstFakeDef>(Zero);
        _addiu(Reg, Zero, Value);
      } else {
        uint32_t UpperBits = (Value >> 16) & 0xFFFF;
        uint32_t LowerBits = Value & 0xFFFF;
        Variable *TReg = makeReg(Ty, RegNum);
        if (LowerBits) {
          _lui(TReg, Ctx->getConstantInt32(UpperBits));
          _ori(Reg, TReg, LowerBits);
        } else {
          _lui(Reg, Ctx->getConstantInt32(UpperBits));
        }
      }
      return Reg;
    } else if (isScalarFloatingType(Ty)) {
      auto *CFrom = llvm::cast<Constant>(From);
      Variable *TReg = makeReg(Ty);
      if (!CFrom->getShouldBePooled()) {
        // Float/Double constant 0 is not pooled.
        Context.insert<InstFakeDef>(TReg);
        _mov(TReg, getZero());
      } else {
        // Load floats/doubles from literal pool.
        Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName());
        Variable *TReg1 = makeReg(getPointerType());
        _lui(TReg1, Offset, RO_Hi);
        OperandMIPS32Mem *Addr =
            OperandMIPS32Mem::create(Func, Ty, TReg1, Offset);
        if (Ty == IceType_f32)
          Sandboxer(this).lwc1(TReg, Addr, RO_Lo);
        else
          Sandboxer(this).ldc1(TReg, Addr, RO_Lo);
      }
      return copyToReg(TReg, RegNum);
    }
  }

  if (auto *Var = llvm::dyn_cast<Variable>(From)) {
    if (Var->isRematerializable()) {
      if (Allowed & Legal_Rematerializable) {
        return From;
      }

      Variable *T = makeReg(Var->getType(), RegNum);
      _mov(T, Var);
      return T;
    }
    // Check if the variable is guaranteed a physical register.  This
    // can happen either when the variable is pre-colored or when it is
    // assigned infinite weight.
    bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
    // We need a new physical register for the operand if:
    //   Mem is not allowed and Var isn't guaranteed a physical
    //   register, or
    //   RegNum is required and Var->getRegNum() doesn't match.
    if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
        (RegNum.hasValue() && RegNum != Var->getRegNum())) {
      From = copyToReg(From, RegNum);
    }
    return From;
  }
  return From;
}

namespace BoolFolding {
// TODO(sagar.thakur): Add remaining instruction kinds to shouldTrackProducer()
// and isValidConsumer()
bool shouldTrackProducer(const Inst &Instr) {
  return Instr.getKind() == Inst::Icmp;
}

bool isValidConsumer(const Inst &Instr) { return Instr.getKind() == Inst::Br; }
} // end of namespace BoolFolding

void TargetMIPS32::ComputationTracker::recordProducers(CfgNode *Node) {
  for (Inst &Instr : Node->getInsts()) {
    if (Instr.isDeleted())
      continue;
    // Check whether Instr is a valid producer.
    Variable *Dest = Instr.getDest();
    if (Dest // only consider instructions with an actual dest var; and
        && Dest->getType() == IceType_i1 // only bool-type dest vars; and
        && BoolFolding::shouldTrackProducer(Instr)) { // white-listed instr.
      KnownComputations.emplace(Dest->getIndex(),
                                ComputationEntry(&Instr, IceType_i1));
    }
    // Check each src variable against the map.
    FOREACH_VAR_IN_INST(Var, Instr) {
      SizeT VarNum = Var->getIndex();
      auto ComputationIter = KnownComputations.find(VarNum);
      if (ComputationIter == KnownComputations.end()) {
        continue;
      }

      ++ComputationIter->second.NumUses;
      switch (ComputationIter->second.ComputationType) {
      default:
        KnownComputations.erase(VarNum);
        continue;
      case IceType_i1:
        if (!BoolFolding::isValidConsumer(Instr)) {
          KnownComputations.erase(VarNum);
          continue;
        }
        break;
      }

      if (Instr.isLastUse(Var)) {
        ComputationIter->second.IsLiveOut = false;
      }
    }
  }

  for (auto Iter = KnownComputations.begin(), End = KnownComputations.end();
       Iter != End;) {
    // Disable the folding if its dest may be live beyond this block.
    if (Iter->second.IsLiveOut || Iter->second.NumUses > 1) {
      Iter = KnownComputations.erase(Iter);
      continue;
    }

    // Mark as "dead" rather than outright deleting. This is so that other
    // peephole style optimizations during or before lowering have access to
    // this instruction in undeleted form. See for example
    // tryOptimizedCmpxchgCmpBr().
    Iter->second.Instr->setDead();
    ++Iter;
  }
}

TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
    : TargetHeaderLowering(Ctx) {}

void TargetHeaderMIPS32::lower() {
  OstreamLocker L(Ctx);
  Ostream &Str = Ctx->getStrEmit();
  Str << "\t.set\t"
      << "nomicromips\n";
  Str << "\t.set\t"
      << "nomips16\n";
  Str << "\t.set\t"
      << "noat\n";
}

SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];

TargetMIPS32::Sandboxer::Sandboxer(TargetMIPS32 *Target,
                                   InstBundleLock::Option BundleOption)
    : Target(Target), BundleOption(BundleOption) {}

TargetMIPS32::Sandboxer::~Sandboxer() {}

void TargetMIPS32::Sandboxer::createAutoBundle() {
  Bundler = makeUnique<AutoBundle>(Target, BundleOption);
}

void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) {
  Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP);
  if (!Target->NeedSandboxing) {
    Target->_addiu(SP, SP, StackOffset);
    return;
  }
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  createAutoBundle();
  Target->_addiu(SP, SP, StackOffset);
  Target->_and(SP, SP, T7);
}

void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) {
  Variable *Base = Mem->getBase();
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) {
    createAutoBundle();
    Target->_and(Base, Base, T7);
  }
  Target->_lw(Dest, Mem);
}

void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) {
  Variable *Base = Mem->getBase();
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) {
    createAutoBundle();
    Target->_and(Base, Base, T7);
  }
  Target->_sw(Dest, Mem);
}

void TargetMIPS32::Sandboxer::lwc1(Variable *Dest, OperandMIPS32Mem *Mem,
                                   RelocOp Reloc) {
  Variable *Base = Mem->getBase();
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) {
    createAutoBundle();
    Target->_and(Base, Base, T7);
  }
  Target->_lwc1(Dest, Mem, Reloc);
  if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg()))
    Target->_and(Dest, Dest, T7);
}

void TargetMIPS32::Sandboxer::ldc1(Variable *Dest, OperandMIPS32Mem *Mem,
                                   RelocOp Reloc) {
  Variable *Base = Mem->getBase();
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) {
    createAutoBundle();
    Target->_and(Base, Base, T7);
  }
  Target->_ldc1(Dest, Mem, Reloc);
  if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg()))
    Target->_and(Dest, Dest, T7);
}

void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) {
  if (!Target->NeedSandboxing) {
    Target->_ret(RetAddr, RetValue);
  }
  Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6);
  createAutoBundle();
  Target->_and(RetAddr, RetAddr, T6);
  Target->_ret(RetAddr, RetValue);
}

void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) {
  Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP);
  if (!Target->NeedSandboxing) {
    Target->_mov(SP, Src);
    return;
  }
  Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7);
  createAutoBundle();
  Target->_mov(SP, Src);
  Target->_and(SP, SP, T7);
}

InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg,
                                             Operand *CallTarget) {
  if (Target->NeedSandboxing)
    createAutoBundle();
  return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget);
}

} // end of namespace MIPS32
} // end of namespace Ice
