2169 lines · cpp
1//===- MipsFastISel.cpp - Mips FastISel implementation --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file defines the MIPS-specific support for the FastISel class.11/// Some of the target-specific code is generated by tablegen in the file12/// MipsGenFastISel.inc, which is #included here.13///14//===----------------------------------------------------------------------===//15 16#include "MCTargetDesc/MipsABIInfo.h"17#include "MCTargetDesc/MipsBaseInfo.h"18#include "MipsCCState.h"19#include "MipsISelLowering.h"20#include "MipsInstrInfo.h"21#include "MipsMachineFunction.h"22#include "MipsSubtarget.h"23#include "MipsTargetMachine.h"24#include "llvm/ADT/APInt.h"25#include "llvm/ADT/DenseMap.h"26#include "llvm/ADT/SmallVector.h"27#include "llvm/Analysis/TargetLibraryInfo.h"28#include "llvm/CodeGen/CallingConvLower.h"29#include "llvm/CodeGen/FastISel.h"30#include "llvm/CodeGen/FunctionLoweringInfo.h"31#include "llvm/CodeGen/ISDOpcodes.h"32#include "llvm/CodeGen/MachineBasicBlock.h"33#include "llvm/CodeGen/MachineFrameInfo.h"34#include "llvm/CodeGen/MachineInstrBuilder.h"35#include "llvm/CodeGen/MachineMemOperand.h"36#include "llvm/CodeGen/MachineRegisterInfo.h"37#include "llvm/CodeGen/TargetInstrInfo.h"38#include "llvm/CodeGen/TargetLowering.h"39#include "llvm/CodeGen/ValueTypes.h"40#include "llvm/CodeGenTypes/MachineValueType.h"41#include "llvm/IR/Attributes.h"42#include "llvm/IR/CallingConv.h"43#include "llvm/IR/Constant.h"44#include "llvm/IR/Constants.h"45#include "llvm/IR/DataLayout.h"46#include "llvm/IR/Function.h"47#include "llvm/IR/GetElementPtrTypeIterator.h"48#include "llvm/IR/GlobalValue.h"49#include "llvm/IR/GlobalVariable.h"50#include "llvm/IR/InstrTypes.h"51#include "llvm/IR/Instruction.h"52#include "llvm/IR/Instructions.h"53#include "llvm/IR/IntrinsicInst.h"54#include "llvm/IR/Operator.h"55#include "llvm/IR/Type.h"56#include "llvm/IR/User.h"57#include "llvm/IR/Value.h"58#include "llvm/MC/MCContext.h"59#include "llvm/MC/MCInstrDesc.h"60#include "llvm/MC/MCSymbol.h"61#include "llvm/Support/Casting.h"62#include "llvm/Support/Compiler.h"63#include "llvm/Support/Debug.h"64#include "llvm/Support/ErrorHandling.h"65#include "llvm/Support/MathExtras.h"66#include "llvm/Support/raw_ostream.h"67#include <algorithm>68#include <array>69#include <cassert>70#include <cstdint>71 72#define DEBUG_TYPE "mips-fastisel"73 74using namespace llvm;75 76extern cl::opt<bool> EmitJalrReloc;77 78namespace {79 80class MipsFastISel final : public FastISel {81 82 // All possible address modes.83 class Address {84 public:85 enum BaseKind { RegBase, FrameIndexBase };86 87 private:88 BaseKind Kind = RegBase;89 union {90 unsigned Reg;91 int FI;92 } Base;93 94 int64_t Offset = 0;95 96 const GlobalValue *GV = nullptr;97 98 public:99 // Innocuous defaults for our address.100 Address() { Base.Reg = 0; }101 102 void setKind(BaseKind K) { Kind = K; }103 BaseKind getKind() const { return Kind; }104 bool isRegBase() const { return Kind == RegBase; }105 bool isFIBase() const { return Kind == FrameIndexBase; }106 107 void setReg(unsigned Reg) {108 assert(isRegBase() && "Invalid base register access!");109 Base.Reg = Reg;110 }111 112 unsigned getReg() const {113 assert(isRegBase() && "Invalid base register access!");114 return Base.Reg;115 }116 117 void setFI(unsigned FI) {118 assert(isFIBase() && "Invalid base frame index access!");119 Base.FI = FI;120 }121 122 unsigned getFI() const {123 assert(isFIBase() && "Invalid base frame index access!");124 return Base.FI;125 }126 127 void setOffset(int64_t Offset_) { Offset = Offset_; }128 int64_t getOffset() const { return Offset; }129 void setGlobalValue(const GlobalValue *G) { GV = G; }130 const GlobalValue *getGlobalValue() { return GV; }131 };132 133 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can134 /// make the right decision when generating code for different targets.135 const TargetMachine &TM;136 const MipsSubtarget *Subtarget;137 const TargetInstrInfo &TII;138 const TargetLowering &TLI;139 MipsFunctionInfo *MFI;140 141 // Convenience variables to avoid some queries.142 LLVMContext *Context;143 144 bool fastLowerArguments() override;145 bool fastLowerCall(CallLoweringInfo &CLI) override;146 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;147 148 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle149 // floating point but not reject doing fast-isel in other150 // situations151 152private:153 // Selection routines.154 bool selectLogicalOp(const Instruction *I);155 bool selectLoad(const Instruction *I);156 bool selectStore(const Instruction *I);157 bool selectBranch(const Instruction *I);158 bool selectSelect(const Instruction *I);159 bool selectCmp(const Instruction *I);160 bool selectFPExt(const Instruction *I);161 bool selectFPTrunc(const Instruction *I);162 bool selectFPToInt(const Instruction *I, bool IsSigned);163 bool selectRet(const Instruction *I);164 bool selectTrunc(const Instruction *I);165 bool selectIntExt(const Instruction *I);166 bool selectShift(const Instruction *I);167 bool selectDivRem(const Instruction *I, unsigned ISDOpcode);168 169 // Utility helper routines.170 bool isTypeLegal(Type *Ty, MVT &VT);171 bool isTypeSupported(Type *Ty, MVT &VT);172 bool isLoadTypeLegal(Type *Ty, MVT &VT);173 bool computeAddress(const Value *Obj, Address &Addr);174 bool computeCallAddress(const Value *V, Address &Addr);175 void simplifyAddress(Address &Addr);176 177 // Emit helper routines.178 bool emitCmp(unsigned DestReg, const CmpInst *CI);179 bool emitLoad(MVT VT, unsigned &ResultReg, Address &Addr);180 bool emitStore(MVT VT, unsigned SrcReg, Address &Addr);181 unsigned emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);182 bool emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,183 184 bool IsZExt);185 bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);186 187 bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);188 bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,189 unsigned DestReg);190 bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,191 unsigned DestReg);192 193 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);194 195 unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,196 const Value *RHS);197 198 unsigned materializeFP(const ConstantFP *CFP, MVT VT);199 unsigned materializeGV(const GlobalValue *GV, MVT VT);200 unsigned materializeInt(const Constant *C, MVT VT);201 unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);202 unsigned materializeExternalCallSym(MCSymbol *Syn);203 204 MachineInstrBuilder emitInst(unsigned Opc) {205 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc));206 }207 208 MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) {209 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),210 DstReg);211 }212 213 MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg,214 unsigned MemReg, int64_t MemOffset) {215 return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);216 }217 218 MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg,219 unsigned MemReg, int64_t MemOffset) {220 return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);221 }222 223 unsigned fastEmitInst_rr(unsigned MachineInstOpcode,224 const TargetRegisterClass *RC,225 unsigned Op0, unsigned Op1);226 227 // for some reason, this default is not generated by tablegen228 // so we explicitly generate it here.229 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,230 unsigned Op0, uint64_t imm1, uint64_t imm2,231 unsigned Op3) {232 return 0;233 }234 235 // Call handling routines.236private:237 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;238 bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs,239 unsigned &NumBytes);240 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);241 242 const MipsABIInfo &getABI() const {243 return static_cast<const MipsTargetMachine &>(TM).getABI();244 }245 246public:247 // Backend specific FastISel code.248 explicit MipsFastISel(FunctionLoweringInfo &funcInfo,249 const TargetLibraryInfo *libInfo)250 : FastISel(funcInfo, libInfo), TM(funcInfo.MF->getTarget()),251 Subtarget(&funcInfo.MF->getSubtarget<MipsSubtarget>()),252 TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) {253 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();254 Context = &funcInfo.Fn->getContext();255 UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat();256 }257 258 Register fastMaterializeAlloca(const AllocaInst *AI) override;259 Register fastMaterializeConstant(const Constant *C) override;260 bool fastSelectInstruction(const Instruction *I) override;261 262#include "MipsGenFastISel.inc"263};264 265} // end anonymous namespace266 267[[maybe_unused]] static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,268 CCValAssign::LocInfo LocInfo,269 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,270 CCState &State);271 272static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT,273 CCValAssign::LocInfo LocInfo,274 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,275 CCState &State) {276 llvm_unreachable("should not be called");277}278 279static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT,280 CCValAssign::LocInfo LocInfo,281 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,282 CCState &State) {283 llvm_unreachable("should not be called");284}285 286#include "MipsGenCallingConv.inc"287 288CCAssignFn *MipsFastISel::CCAssignFnForCall(CallingConv::ID CC) const {289 return CC_MipsO32;290}291 292unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,293 const Value *LHS, const Value *RHS) {294 // Canonicalize immediates to the RHS first.295 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))296 std::swap(LHS, RHS);297 298 unsigned Opc;299 switch (ISDOpc) {300 case ISD::AND:301 Opc = Mips::AND;302 break;303 case ISD::OR:304 Opc = Mips::OR;305 break;306 case ISD::XOR:307 Opc = Mips::XOR;308 break;309 default:310 llvm_unreachable("unexpected opcode");311 }312 313 Register LHSReg = getRegForValue(LHS);314 if (!LHSReg)315 return 0;316 317 unsigned RHSReg;318 if (const auto *C = dyn_cast<ConstantInt>(RHS))319 RHSReg = materializeInt(C, MVT::i32);320 else321 RHSReg = getRegForValue(RHS);322 if (!RHSReg)323 return 0;324 325 Register ResultReg = createResultReg(&Mips::GPR32RegClass);326 if (!ResultReg)327 return 0;328 329 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);330 return ResultReg;331}332 333Register MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) {334 assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 &&335 "Alloca should always return a pointer.");336 337 DenseMap<const AllocaInst *, int>::iterator SI =338 FuncInfo.StaticAllocaMap.find(AI);339 340 if (SI != FuncInfo.StaticAllocaMap.end()) {341 Register ResultReg = createResultReg(&Mips::GPR32RegClass);342 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::LEA_ADDiu),343 ResultReg)344 .addFrameIndex(SI->second)345 .addImm(0);346 return ResultReg;347 }348 349 return Register();350}351 352unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {353 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)354 return 0;355 const TargetRegisterClass *RC = &Mips::GPR32RegClass;356 const ConstantInt *CI = cast<ConstantInt>(C);357 return materialize32BitInt(CI->getZExtValue(), RC);358}359 360unsigned MipsFastISel::materialize32BitInt(int64_t Imm,361 const TargetRegisterClass *RC) {362 Register ResultReg = createResultReg(RC);363 364 if (isInt<16>(Imm)) {365 unsigned Opc = Mips::ADDiu;366 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);367 return ResultReg;368 } else if (isUInt<16>(Imm)) {369 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);370 return ResultReg;371 }372 unsigned Lo = Imm & 0xFFFF;373 unsigned Hi = (Imm >> 16) & 0xFFFF;374 if (Lo) {375 // Both Lo and Hi have nonzero bits.376 Register TmpReg = createResultReg(RC);377 emitInst(Mips::LUi, TmpReg).addImm(Hi);378 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);379 } else {380 emitInst(Mips::LUi, ResultReg).addImm(Hi);381 }382 return ResultReg;383}384 385unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) {386 if (UnsupportedFPMode)387 return 0;388 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();389 if (VT == MVT::f32) {390 const TargetRegisterClass *RC = &Mips::FGR32RegClass;391 Register DestReg = createResultReg(RC);392 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);393 emitInst(Mips::MTC1, DestReg).addReg(TempReg);394 return DestReg;395 } else if (VT == MVT::f64) {396 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;397 Register DestReg = createResultReg(RC);398 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);399 unsigned TempReg2 =400 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);401 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);402 return DestReg;403 }404 return 0;405}406 407unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {408 // For now 32-bit only.409 if (VT != MVT::i32)410 return 0;411 const TargetRegisterClass *RC = &Mips::GPR32RegClass;412 Register DestReg = createResultReg(RC);413 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);414 bool IsThreadLocal = GVar && GVar->isThreadLocal();415 // TLS not supported at this time.416 if (IsThreadLocal)417 return 0;418 emitInst(Mips::LW, DestReg)419 .addReg(MFI->getGlobalBaseReg(*MF))420 .addGlobalAddress(GV, 0, MipsII::MO_GOT);421 if ((GV->hasInternalLinkage() ||422 (GV->hasLocalLinkage() && !isa<Function>(GV)))) {423 Register TempReg = createResultReg(RC);424 emitInst(Mips::ADDiu, TempReg)425 .addReg(DestReg)426 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);427 DestReg = TempReg;428 }429 return DestReg;430}431 432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {433 const TargetRegisterClass *RC = &Mips::GPR32RegClass;434 Register DestReg = createResultReg(RC);435 emitInst(Mips::LW, DestReg)436 .addReg(MFI->getGlobalBaseReg(*MF))437 .addSym(Sym, MipsII::MO_GOT);438 return DestReg;439}440 441// Materialize a constant into a register, and return the register442// number (or zero if we failed to handle it).443Register MipsFastISel::fastMaterializeConstant(const Constant *C) {444 EVT CEVT = TLI.getValueType(DL, C->getType(), true);445 446 // Only handle simple types.447 if (!CEVT.isSimple())448 return Register();449 MVT VT = CEVT.getSimpleVT();450 451 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))452 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);453 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))454 return materializeGV(GV, VT);455 else if (isa<ConstantInt>(C))456 return materializeInt(C, VT);457 458 return Register();459}460 461bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {462 const User *U = nullptr;463 unsigned Opcode = Instruction::UserOp1;464 if (const Instruction *I = dyn_cast<Instruction>(Obj)) {465 // Don't walk into other basic blocks unless the object is an alloca from466 // another block, otherwise it may not have a virtual register assigned.467 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||468 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {469 Opcode = I->getOpcode();470 U = I;471 }472 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {473 Opcode = C->getOpcode();474 U = C;475 }476 switch (Opcode) {477 default:478 break;479 case Instruction::BitCast:480 // Look through bitcasts.481 return computeAddress(U->getOperand(0), Addr);482 case Instruction::GetElementPtr: {483 Address SavedAddr = Addr;484 int64_t TmpOffset = Addr.getOffset();485 // Iterate through the GEP folding the constants into offsets where486 // we can.487 gep_type_iterator GTI = gep_type_begin(U);488 for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e;489 ++i, ++GTI) {490 const Value *Op = *i;491 if (StructType *STy = GTI.getStructTypeOrNull()) {492 const StructLayout *SL = DL.getStructLayout(STy);493 unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();494 TmpOffset += SL->getElementOffset(Idx);495 } else {496 uint64_t S = GTI.getSequentialElementStride(DL);497 while (true) {498 if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {499 // Constant-offset addressing.500 TmpOffset += CI->getSExtValue() * S;501 break;502 }503 if (canFoldAddIntoGEP(U, Op)) {504 // A compatible add with a constant operand. Fold the constant.505 ConstantInt *CI =506 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));507 TmpOffset += CI->getSExtValue() * S;508 // Iterate on the other operand.509 Op = cast<AddOperator>(Op)->getOperand(0);510 continue;511 }512 // Unsupported513 goto unsupported_gep;514 }515 }516 }517 // Try to grab the base operand now.518 Addr.setOffset(TmpOffset);519 if (computeAddress(U->getOperand(0), Addr))520 return true;521 // We failed, restore everything and try the other options.522 Addr = SavedAddr;523 unsupported_gep:524 break;525 }526 case Instruction::Alloca: {527 const AllocaInst *AI = cast<AllocaInst>(Obj);528 DenseMap<const AllocaInst *, int>::iterator SI =529 FuncInfo.StaticAllocaMap.find(AI);530 if (SI != FuncInfo.StaticAllocaMap.end()) {531 Addr.setKind(Address::FrameIndexBase);532 Addr.setFI(SI->second);533 return true;534 }535 break;536 }537 }538 Addr.setReg(getRegForValue(Obj));539 return Addr.getReg() != 0;540}541 542bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {543 const User *U = nullptr;544 unsigned Opcode = Instruction::UserOp1;545 546 if (const auto *I = dyn_cast<Instruction>(V)) {547 // Check if the value is defined in the same basic block. This information548 // is crucial to know whether or not folding an operand is valid.549 if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {550 Opcode = I->getOpcode();551 U = I;552 }553 } else if (const auto *C = dyn_cast<ConstantExpr>(V)) {554 Opcode = C->getOpcode();555 U = C;556 }557 558 switch (Opcode) {559 default:560 break;561 case Instruction::BitCast:562 // Look past bitcasts if its operand is in the same BB.563 return computeCallAddress(U->getOperand(0), Addr);564 break;565 case Instruction::IntToPtr:566 // Look past no-op inttoptrs if its operand is in the same BB.567 if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==568 TLI.getPointerTy(DL))569 return computeCallAddress(U->getOperand(0), Addr);570 break;571 case Instruction::PtrToInt:572 // Look past no-op ptrtoints if its operand is in the same BB.573 if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))574 return computeCallAddress(U->getOperand(0), Addr);575 break;576 }577 578 if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {579 Addr.setGlobalValue(GV);580 return true;581 }582 583 // If all else fails, try to materialize the value in a register.584 if (!Addr.getGlobalValue()) {585 Addr.setReg(getRegForValue(V));586 return Addr.getReg() != 0;587 }588 589 return false;590}591 592bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {593 EVT evt = TLI.getValueType(DL, Ty, true);594 // Only handle simple types.595 if (evt == MVT::Other || !evt.isSimple())596 return false;597 VT = evt.getSimpleVT();598 599 // Handle all legal types, i.e. a register that will directly hold this600 // value.601 return TLI.isTypeLegal(VT);602}603 604bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {605 if (Ty->isVectorTy())606 return false;607 608 if (isTypeLegal(Ty, VT))609 return true;610 611 // If this is a type than can be sign or zero-extended to a basic operation612 // go ahead and accept it now.613 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)614 return true;615 616 return false;617}618 619bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {620 if (isTypeLegal(Ty, VT))621 return true;622 // We will extend this in a later patch:623 // If this is a type than can be sign or zero-extended to a basic operation624 // go ahead and accept it now.625 if (VT == MVT::i8 || VT == MVT::i16)626 return true;627 return false;628}629 630// Because of how EmitCmp is called with fast-isel, you can631// end up with redundant "andi" instructions after the sequences emitted below.632// We should try and solve this issue in the future.633//634bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {635 const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);636 bool IsUnsigned = CI->isUnsigned();637 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);638 if (LeftReg == 0)639 return false;640 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);641 if (RightReg == 0)642 return false;643 CmpInst::Predicate P = CI->getPredicate();644 645 switch (P) {646 default:647 return false;648 case CmpInst::ICMP_EQ: {649 Register TempReg = createResultReg(&Mips::GPR32RegClass);650 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);651 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);652 break;653 }654 case CmpInst::ICMP_NE: {655 Register TempReg = createResultReg(&Mips::GPR32RegClass);656 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);657 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);658 break;659 }660 case CmpInst::ICMP_UGT:661 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);662 break;663 case CmpInst::ICMP_ULT:664 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);665 break;666 case CmpInst::ICMP_UGE: {667 Register TempReg = createResultReg(&Mips::GPR32RegClass);668 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);669 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);670 break;671 }672 case CmpInst::ICMP_ULE: {673 Register TempReg = createResultReg(&Mips::GPR32RegClass);674 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);675 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);676 break;677 }678 case CmpInst::ICMP_SGT:679 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);680 break;681 case CmpInst::ICMP_SLT:682 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);683 break;684 case CmpInst::ICMP_SGE: {685 Register TempReg = createResultReg(&Mips::GPR32RegClass);686 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);687 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);688 break;689 }690 case CmpInst::ICMP_SLE: {691 Register TempReg = createResultReg(&Mips::GPR32RegClass);692 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);693 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);694 break;695 }696 case CmpInst::FCMP_OEQ:697 case CmpInst::FCMP_UNE:698 case CmpInst::FCMP_OLT:699 case CmpInst::FCMP_OLE:700 case CmpInst::FCMP_OGT:701 case CmpInst::FCMP_OGE: {702 if (UnsupportedFPMode)703 return false;704 bool IsFloat = Left->getType()->isFloatTy();705 bool IsDouble = Left->getType()->isDoubleTy();706 if (!IsFloat && !IsDouble)707 return false;708 unsigned Opc, CondMovOpc;709 switch (P) {710 case CmpInst::FCMP_OEQ:711 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;712 CondMovOpc = Mips::MOVT_I;713 break;714 case CmpInst::FCMP_UNE:715 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;716 CondMovOpc = Mips::MOVF_I;717 break;718 case CmpInst::FCMP_OLT:719 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;720 CondMovOpc = Mips::MOVT_I;721 break;722 case CmpInst::FCMP_OLE:723 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;724 CondMovOpc = Mips::MOVT_I;725 break;726 case CmpInst::FCMP_OGT:727 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;728 CondMovOpc = Mips::MOVF_I;729 break;730 case CmpInst::FCMP_OGE:731 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;732 CondMovOpc = Mips::MOVF_I;733 break;734 default:735 llvm_unreachable("Only switching of a subset of CCs.");736 }737 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);738 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);739 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);740 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);741 emitInst(Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)742 .addReg(RightReg);743 emitInst(CondMovOpc, ResultReg)744 .addReg(RegWithOne)745 .addReg(Mips::FCC0)746 .addReg(RegWithZero);747 break;748 }749 }750 return true;751}752 753bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr) {754 //755 // more cases will be handled here in following patches.756 //757 unsigned Opc;758 switch (VT.SimpleTy) {759 case MVT::i32:760 ResultReg = createResultReg(&Mips::GPR32RegClass);761 Opc = Mips::LW;762 break;763 case MVT::i16:764 ResultReg = createResultReg(&Mips::GPR32RegClass);765 Opc = Mips::LHu;766 break;767 case MVT::i8:768 ResultReg = createResultReg(&Mips::GPR32RegClass);769 Opc = Mips::LBu;770 break;771 case MVT::f32:772 if (UnsupportedFPMode)773 return false;774 ResultReg = createResultReg(&Mips::FGR32RegClass);775 Opc = Mips::LWC1;776 break;777 case MVT::f64:778 if (UnsupportedFPMode)779 return false;780 ResultReg = createResultReg(&Mips::AFGR64RegClass);781 Opc = Mips::LDC1;782 break;783 default:784 return false;785 }786 if (Addr.isRegBase()) {787 simplifyAddress(Addr);788 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());789 return true;790 }791 if (Addr.isFIBase()) {792 unsigned FI = Addr.getFI();793 int64_t Offset = Addr.getOffset();794 MachineFrameInfo &MFI = MF->getFrameInfo();795 MachineMemOperand *MMO = MF->getMachineMemOperand(796 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,797 MFI.getObjectSize(FI), Align(4));798 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)799 .addFrameIndex(FI)800 .addImm(Offset)801 .addMemOperand(MMO);802 return true;803 }804 return false;805}806 807bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr) {808 //809 // more cases will be handled here in following patches.810 //811 unsigned Opc;812 switch (VT.SimpleTy) {813 case MVT::i8:814 Opc = Mips::SB;815 break;816 case MVT::i16:817 Opc = Mips::SH;818 break;819 case MVT::i32:820 Opc = Mips::SW;821 break;822 case MVT::f32:823 if (UnsupportedFPMode)824 return false;825 Opc = Mips::SWC1;826 break;827 case MVT::f64:828 if (UnsupportedFPMode)829 return false;830 Opc = Mips::SDC1;831 break;832 default:833 return false;834 }835 if (Addr.isRegBase()) {836 simplifyAddress(Addr);837 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());838 return true;839 }840 if (Addr.isFIBase()) {841 unsigned FI = Addr.getFI();842 int64_t Offset = Addr.getOffset();843 MachineFrameInfo &MFI = MF->getFrameInfo();844 MachineMemOperand *MMO = MF->getMachineMemOperand(845 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,846 MFI.getObjectSize(FI), Align(4));847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))848 .addReg(SrcReg)849 .addFrameIndex(FI)850 .addImm(Offset)851 .addMemOperand(MMO);852 return true;853 }854 return false;855}856 857bool MipsFastISel::selectLogicalOp(const Instruction *I) {858 MVT VT;859 if (!isTypeSupported(I->getType(), VT))860 return false;861 862 unsigned ResultReg;863 switch (I->getOpcode()) {864 default:865 llvm_unreachable("Unexpected instruction.");866 case Instruction::And:867 ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));868 break;869 case Instruction::Or:870 ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));871 break;872 case Instruction::Xor:873 ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));874 break;875 }876 877 if (!ResultReg)878 return false;879 880 updateValueMap(I, ResultReg);881 return true;882}883 884bool MipsFastISel::selectLoad(const Instruction *I) {885 const LoadInst *LI = cast<LoadInst>(I);886 887 // Atomic loads need special handling.888 if (LI->isAtomic())889 return false;890 891 // Verify we have a legal type before going any further.892 MVT VT;893 if (!isLoadTypeLegal(LI->getType(), VT))894 return false;895 896 // Underaligned loads need special handling.897 if (LI->getAlign() < VT.getFixedSizeInBits() / 8 &&898 !Subtarget->systemSupportsUnalignedAccess())899 return false;900 901 // See if we can handle this address.902 Address Addr;903 if (!computeAddress(LI->getOperand(0), Addr))904 return false;905 906 unsigned ResultReg;907 if (!emitLoad(VT, ResultReg, Addr))908 return false;909 updateValueMap(LI, ResultReg);910 return true;911}912 913bool MipsFastISel::selectStore(const Instruction *I) {914 const StoreInst *SI = cast<StoreInst>(I);915 916 Value *Op0 = SI->getOperand(0);917 unsigned SrcReg = 0;918 919 // Atomic stores need special handling.920 if (SI->isAtomic())921 return false;922 923 // Verify we have a legal type before going any further.924 MVT VT;925 if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))926 return false;927 928 // Underaligned stores need special handling.929 if (SI->getAlign() < VT.getFixedSizeInBits() / 8 &&930 !Subtarget->systemSupportsUnalignedAccess())931 return false;932 933 // Get the value to be stored into a register.934 SrcReg = getRegForValue(Op0);935 if (SrcReg == 0)936 return false;937 938 // See if we can handle this address.939 Address Addr;940 if (!computeAddress(SI->getOperand(1), Addr))941 return false;942 943 if (!emitStore(VT, SrcReg, Addr))944 return false;945 return true;946}947 948// This can cause a redundant sltiu to be generated.949// FIXME: try and eliminate this in a future patch.950bool MipsFastISel::selectBranch(const Instruction *I) {951 const BranchInst *BI = cast<BranchInst>(I);952 MachineBasicBlock *BrBB = FuncInfo.MBB;953 //954 // TBB is the basic block for the case where the comparison is true.955 // FBB is the basic block for the case where the comparison is false.956 // if (cond) goto TBB957 // goto FBB958 // TBB:959 //960 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));961 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));962 963 // Fold the common case of a conditional branch with a comparison964 // in the same block.965 unsigned ZExtCondReg = 0;966 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {967 if (CI->hasOneUse() && CI->getParent() == I->getParent()) {968 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);969 if (!emitCmp(ZExtCondReg, CI))970 return false;971 }972 }973 974 // For the general case, we need to mask with 1.975 if (ZExtCondReg == 0) {976 Register CondReg = getRegForValue(BI->getCondition());977 if (CondReg == 0)978 return false;979 980 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);981 if (ZExtCondReg == 0)982 return false;983 }984 985 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::BGTZ))986 .addReg(ZExtCondReg)987 .addMBB(TBB);988 finishCondBranch(BI->getParent(), TBB, FBB);989 return true;990}991 992bool MipsFastISel::selectCmp(const Instruction *I) {993 const CmpInst *CI = cast<CmpInst>(I);994 Register ResultReg = createResultReg(&Mips::GPR32RegClass);995 if (!emitCmp(ResultReg, CI))996 return false;997 updateValueMap(I, ResultReg);998 return true;999}1000 1001// Attempt to fast-select a floating-point extend instruction.1002bool MipsFastISel::selectFPExt(const Instruction *I) {1003 if (UnsupportedFPMode)1004 return false;1005 Value *Src = I->getOperand(0);1006 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);1007 EVT DestVT = TLI.getValueType(DL, I->getType(), true);1008 1009 if (SrcVT != MVT::f32 || DestVT != MVT::f64)1010 return false;1011 1012 Register SrcReg =1013 getRegForValue(Src); // this must be a 32bit floating point register class1014 // maybe we should handle this differently1015 if (!SrcReg)1016 return false;1017 1018 Register DestReg = createResultReg(&Mips::AFGR64RegClass);1019 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);1020 updateValueMap(I, DestReg);1021 return true;1022}1023 1024bool MipsFastISel::selectSelect(const Instruction *I) {1025 assert(isa<SelectInst>(I) && "Expected a select instruction.");1026 1027 LLVM_DEBUG(dbgs() << "selectSelect\n");1028 1029 MVT VT;1030 if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {1031 LLVM_DEBUG(1032 dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");1033 return false;1034 }1035 1036 unsigned CondMovOpc;1037 const TargetRegisterClass *RC;1038 1039 if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {1040 CondMovOpc = Mips::MOVN_I_I;1041 RC = &Mips::GPR32RegClass;1042 } else if (VT == MVT::f32) {1043 CondMovOpc = Mips::MOVN_I_S;1044 RC = &Mips::FGR32RegClass;1045 } else if (VT == MVT::f64) {1046 CondMovOpc = Mips::MOVN_I_D32;1047 RC = &Mips::AFGR64RegClass;1048 } else1049 return false;1050 1051 const SelectInst *SI = cast<SelectInst>(I);1052 const Value *Cond = SI->getCondition();1053 Register Src1Reg = getRegForValue(SI->getTrueValue());1054 Register Src2Reg = getRegForValue(SI->getFalseValue());1055 Register CondReg = getRegForValue(Cond);1056 1057 if (!Src1Reg || !Src2Reg || !CondReg)1058 return false;1059 1060 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);1061 if (!ZExtCondReg)1062 return false;1063 1064 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg, true))1065 return false;1066 1067 Register ResultReg = createResultReg(RC);1068 Register TempReg = createResultReg(RC);1069 1070 if (!ResultReg || !TempReg)1071 return false;1072 1073 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);1074 emitInst(CondMovOpc, ResultReg)1075 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);1076 updateValueMap(I, ResultReg);1077 return true;1078}1079 1080// Attempt to fast-select a floating-point truncate instruction.1081bool MipsFastISel::selectFPTrunc(const Instruction *I) {1082 if (UnsupportedFPMode)1083 return false;1084 Value *Src = I->getOperand(0);1085 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);1086 EVT DestVT = TLI.getValueType(DL, I->getType(), true);1087 1088 if (SrcVT != MVT::f64 || DestVT != MVT::f32)1089 return false;1090 1091 Register SrcReg = getRegForValue(Src);1092 if (!SrcReg)1093 return false;1094 1095 Register DestReg = createResultReg(&Mips::FGR32RegClass);1096 if (!DestReg)1097 return false;1098 1099 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);1100 updateValueMap(I, DestReg);1101 return true;1102}1103 1104// Attempt to fast-select a floating-point-to-integer conversion.1105bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {1106 if (UnsupportedFPMode)1107 return false;1108 MVT DstVT, SrcVT;1109 if (!IsSigned)1110 return false; // We don't handle this case yet. There is no native1111 // instruction for this but it can be synthesized.1112 Type *DstTy = I->getType();1113 if (!isTypeLegal(DstTy, DstVT))1114 return false;1115 1116 if (DstVT != MVT::i32)1117 return false;1118 1119 Value *Src = I->getOperand(0);1120 Type *SrcTy = Src->getType();1121 if (!isTypeLegal(SrcTy, SrcVT))1122 return false;1123 1124 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)1125 return false;1126 1127 Register SrcReg = getRegForValue(Src);1128 if (SrcReg == 0)1129 return false;1130 1131 // Determine the opcode for the conversion, which takes place1132 // entirely within FPRs.1133 Register DestReg = createResultReg(&Mips::GPR32RegClass);1134 Register TempReg = createResultReg(&Mips::FGR32RegClass);1135 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;1136 1137 // Generate the convert.1138 emitInst(Opc, TempReg).addReg(SrcReg);1139 emitInst(Mips::MFC1, DestReg).addReg(TempReg);1140 1141 updateValueMap(I, DestReg);1142 return true;1143}1144 1145bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,1146 SmallVectorImpl<MVT> &OutVTs,1147 unsigned &NumBytes) {1148 CallingConv::ID CC = CLI.CallConv;1149 SmallVector<CCValAssign, 16> ArgLocs;1150 SmallVector<Type *, 16> ArgTys;1151 for (const ArgListEntry &Arg : CLI.Args)1152 ArgTys.push_back(Arg.Val->getType());1153 CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);1154 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,1155 CCAssignFnForCall(CC));1156 // Get a count of how many bytes are to be pushed on the stack.1157 NumBytes = CCInfo.getStackSize();1158 // This is the minimum argument area used for A0-A3.1159 if (NumBytes < 16)1160 NumBytes = 16;1161 1162 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);1163 // Process the args.1164 MVT firstMVT;1165 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {1166 CCValAssign &VA = ArgLocs[i];1167 const Value *ArgVal = CLI.OutVals[VA.getValNo()];1168 MVT ArgVT = OutVTs[VA.getValNo()];1169 1170 if (i == 0) {1171 firstMVT = ArgVT;1172 if (ArgVT == MVT::f32) {1173 VA.convertToReg(Mips::F12);1174 } else if (ArgVT == MVT::f64) {1175 if (Subtarget->isFP64bit())1176 VA.convertToReg(Mips::D6_64);1177 else1178 VA.convertToReg(Mips::D6);1179 }1180 } else if (i == 1) {1181 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {1182 if (ArgVT == MVT::f32) {1183 VA.convertToReg(Mips::F14);1184 } else if (ArgVT == MVT::f64) {1185 if (Subtarget->isFP64bit())1186 VA.convertToReg(Mips::D7_64);1187 else1188 VA.convertToReg(Mips::D7);1189 }1190 }1191 }1192 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||1193 (ArgVT == MVT::i8)) &&1194 VA.isMemLoc()) {1195 switch (VA.getLocMemOffset()) {1196 case 0:1197 VA.convertToReg(Mips::A0);1198 break;1199 case 4:1200 VA.convertToReg(Mips::A1);1201 break;1202 case 8:1203 VA.convertToReg(Mips::A2);1204 break;1205 case 12:1206 VA.convertToReg(Mips::A3);1207 break;1208 default:1209 break;1210 }1211 }1212 Register ArgReg = getRegForValue(ArgVal);1213 if (!ArgReg)1214 return false;1215 1216 // Handle arg promotion: SExt, ZExt, AExt.1217 switch (VA.getLocInfo()) {1218 case CCValAssign::Full:1219 break;1220 case CCValAssign::AExt:1221 case CCValAssign::SExt: {1222 MVT DestVT = VA.getLocVT();1223 MVT SrcVT = ArgVT;1224 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/false);1225 if (!ArgReg)1226 return false;1227 break;1228 }1229 case CCValAssign::ZExt: {1230 MVT DestVT = VA.getLocVT();1231 MVT SrcVT = ArgVT;1232 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/true);1233 if (!ArgReg)1234 return false;1235 break;1236 }1237 default:1238 llvm_unreachable("Unknown arg promotion!");1239 }1240 1241 // Now copy/store arg to correct locations.1242 if (VA.isRegLoc() && !VA.needsCustom()) {1243 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1244 TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg);1245 CLI.OutRegs.push_back(VA.getLocReg());1246 } else if (VA.needsCustom()) {1247 llvm_unreachable("Mips does not use custom args.");1248 return false;1249 } else {1250 //1251 // FIXME: This path will currently return false. It was copied1252 // from the AArch64 port and should be essentially fine for Mips too.1253 // The work to finish up this path will be done in a follow-on patch.1254 //1255 assert(VA.isMemLoc() && "Assuming store on stack.");1256 // Don't emit stores for undef values.1257 if (isa<UndefValue>(ArgVal))1258 continue;1259 1260 // Need to store on the stack.1261 // FIXME: This alignment is incorrect but this path is disabled1262 // for now (will return false). We need to determine the right alignment1263 // based on the normal alignment for the underlying machine type.1264 //1265 unsigned ArgSize = alignTo(ArgVT.getSizeInBits(), 4);1266 1267 unsigned BEAlign = 0;1268 if (ArgSize < 8 && !Subtarget->isLittle())1269 BEAlign = 8 - ArgSize;1270 1271 Address Addr;1272 Addr.setKind(Address::RegBase);1273 Addr.setReg(Mips::SP);1274 Addr.setOffset(VA.getLocMemOffset() + BEAlign);1275 1276 Align Alignment = DL.getABITypeAlign(ArgVal->getType());1277 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(1278 MachinePointerInfo::getStack(*FuncInfo.MF, Addr.getOffset()),1279 MachineMemOperand::MOStore, ArgVT.getStoreSize(), Alignment);1280 (void)(MMO);1281 // if (!emitStore(ArgVT, ArgReg, Addr, MMO))1282 return false; // can't store on the stack yet.1283 }1284 }1285 1286 return true;1287}1288 1289bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,1290 unsigned NumBytes) {1291 CallingConv::ID CC = CLI.CallConv;1292 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);1293 if (RetVT != MVT::isVoid) {1294 SmallVector<CCValAssign, 16> RVLocs;1295 MipsCCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);1296 1297 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);1298 1299 // Only handle a single return value.1300 if (RVLocs.size() != 1)1301 return false;1302 // Copy all of the result registers out of their specified physreg.1303 MVT CopyVT = RVLocs[0].getValVT();1304 // Special handling for extended integers.1305 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)1306 CopyVT = MVT::i32;1307 1308 Register ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));1309 if (!ResultReg)1310 return false;1311 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1312 TII.get(TargetOpcode::COPY),1313 ResultReg).addReg(RVLocs[0].getLocReg());1314 CLI.InRegs.push_back(RVLocs[0].getLocReg());1315 1316 CLI.ResultReg = ResultReg;1317 CLI.NumResultRegs = 1;1318 }1319 return true;1320}1321 1322bool MipsFastISel::fastLowerArguments() {1323 LLVM_DEBUG(dbgs() << "fastLowerArguments\n");1324 1325 if (!FuncInfo.CanLowerReturn) {1326 LLVM_DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n");1327 return false;1328 }1329 1330 const Function *F = FuncInfo.Fn;1331 if (F->isVarArg()) {1332 LLVM_DEBUG(dbgs() << ".. gave up (varargs)\n");1333 return false;1334 }1335 1336 CallingConv::ID CC = F->getCallingConv();1337 if (CC != CallingConv::C) {1338 LLVM_DEBUG(dbgs() << ".. gave up (calling convention is not C)\n");1339 return false;1340 }1341 1342 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,1343 Mips::A3}};1344 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};1345 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};1346 auto NextGPR32 = GPR32ArgRegs.begin();1347 auto NextFGR32 = FGR32ArgRegs.begin();1348 auto NextAFGR64 = AFGR64ArgRegs.begin();1349 1350 struct AllocatedReg {1351 const TargetRegisterClass *RC;1352 unsigned Reg;1353 AllocatedReg(const TargetRegisterClass *RC, unsigned Reg)1354 : RC(RC), Reg(Reg) {}1355 };1356 1357 // Only handle simple cases. i.e. All arguments are directly mapped to1358 // registers of the appropriate type.1359 SmallVector<AllocatedReg, 4> Allocation;1360 for (const auto &FormalArg : F->args()) {1361 if (FormalArg.hasAttribute(Attribute::InReg) ||1362 FormalArg.hasAttribute(Attribute::StructRet) ||1363 FormalArg.hasAttribute(Attribute::ByVal)) {1364 LLVM_DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n");1365 return false;1366 }1367 1368 Type *ArgTy = FormalArg.getType();1369 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {1370 LLVM_DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n");1371 return false;1372 }1373 1374 EVT ArgVT = TLI.getValueType(DL, ArgTy);1375 LLVM_DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": "1376 << ArgVT << "\n");1377 if (!ArgVT.isSimple()) {1378 LLVM_DEBUG(dbgs() << ".. .. gave up (not a simple type)\n");1379 return false;1380 }1381 1382 switch (ArgVT.getSimpleVT().SimpleTy) {1383 case MVT::i1:1384 case MVT::i8:1385 case MVT::i16:1386 if (!FormalArg.hasAttribute(Attribute::SExt) &&1387 !FormalArg.hasAttribute(Attribute::ZExt)) {1388 // It must be any extend, this shouldn't happen for clang-generated IR1389 // so just fall back on SelectionDAG.1390 LLVM_DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n");1391 return false;1392 }1393 1394 if (NextGPR32 == GPR32ArgRegs.end()) {1395 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");1396 return false;1397 }1398 1399 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");1400 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);1401 1402 // Allocating any GPR32 prohibits further use of floating point arguments.1403 NextFGR32 = FGR32ArgRegs.end();1404 NextAFGR64 = AFGR64ArgRegs.end();1405 break;1406 1407 case MVT::i32:1408 if (FormalArg.hasAttribute(Attribute::ZExt)) {1409 // The O32 ABI does not permit a zero-extended i32.1410 LLVM_DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n");1411 return false;1412 }1413 1414 if (NextGPR32 == GPR32ArgRegs.end()) {1415 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");1416 return false;1417 }1418 1419 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");1420 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);1421 1422 // Allocating any GPR32 prohibits further use of floating point arguments.1423 NextFGR32 = FGR32ArgRegs.end();1424 NextAFGR64 = AFGR64ArgRegs.end();1425 break;1426 1427 case MVT::f32:1428 if (UnsupportedFPMode) {1429 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");1430 return false;1431 }1432 if (NextFGR32 == FGR32ArgRegs.end()) {1433 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n");1434 return false;1435 }1436 LLVM_DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n");1437 Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++);1438 // Allocating an FGR32 also allocates the super-register AFGR64, and1439 // ABI rules require us to skip the corresponding GPR32.1440 if (NextGPR32 != GPR32ArgRegs.end())1441 NextGPR32++;1442 if (NextAFGR64 != AFGR64ArgRegs.end())1443 NextAFGR64++;1444 break;1445 1446 case MVT::f64:1447 if (UnsupportedFPMode) {1448 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");1449 return false;1450 }1451 if (NextAFGR64 == AFGR64ArgRegs.end()) {1452 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");1453 return false;1454 }1455 LLVM_DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n");1456 Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);1457 // Allocating an FGR32 also allocates the super-register AFGR64, and1458 // ABI rules require us to skip the corresponding GPR32 pair.1459 if (NextGPR32 != GPR32ArgRegs.end())1460 NextGPR32++;1461 if (NextGPR32 != GPR32ArgRegs.end())1462 NextGPR32++;1463 if (NextFGR32 != FGR32ArgRegs.end())1464 NextFGR32++;1465 break;1466 1467 default:1468 LLVM_DEBUG(dbgs() << ".. .. gave up (unknown type)\n");1469 return false;1470 }1471 }1472 1473 for (const auto &FormalArg : F->args()) {1474 unsigned ArgNo = FormalArg.getArgNo();1475 unsigned SrcReg = Allocation[ArgNo].Reg;1476 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);1477 // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.1478 // Without this, EmitLiveInCopies may eliminate the livein if its only1479 // use is a bitcast (which isn't turned into an instruction).1480 Register ResultReg = createResultReg(Allocation[ArgNo].RC);1481 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1482 TII.get(TargetOpcode::COPY), ResultReg)1483 .addReg(DstReg, getKillRegState(true));1484 updateValueMap(&FormalArg, ResultReg);1485 }1486 1487 // Calculate the size of the incoming arguments area.1488 // We currently reject all the cases where this would be non-zero.1489 unsigned IncomingArgSizeInBytes = 0;1490 1491 // Account for the reserved argument area on ABI's that have one (O32).1492 // It seems strange to do this on the caller side but it's necessary in1493 // SelectionDAG's implementation.1494 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),1495 IncomingArgSizeInBytes);1496 1497 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,1498 false);1499 1500 return true;1501}1502 1503bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {1504 CallingConv::ID CC = CLI.CallConv;1505 bool IsTailCall = CLI.IsTailCall;1506 bool IsVarArg = CLI.IsVarArg;1507 const Value *Callee = CLI.Callee;1508 MCSymbol *Symbol = CLI.Symbol;1509 1510 // Do not handle FastCC.1511 if (CC == CallingConv::Fast)1512 return false;1513 1514 // Allow SelectionDAG isel to handle tail calls.1515 if (IsTailCall)1516 return false;1517 1518 // Let SDISel handle vararg functions.1519 if (IsVarArg)1520 return false;1521 1522 // FIXME: Only handle *simple* calls for now.1523 MVT RetVT;1524 if (CLI.RetTy->isVoidTy())1525 RetVT = MVT::isVoid;1526 else if (!isTypeSupported(CLI.RetTy, RetVT))1527 return false;1528 1529 for (auto Flag : CLI.OutFlags)1530 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())1531 return false;1532 1533 // Set up the argument vectors.1534 SmallVector<MVT, 16> OutVTs;1535 OutVTs.reserve(CLI.OutVals.size());1536 1537 for (auto *Val : CLI.OutVals) {1538 MVT VT;1539 if (!isTypeLegal(Val->getType(), VT) &&1540 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))1541 return false;1542 1543 // We don't handle vector parameters yet.1544 if (VT.isVector() || VT.getSizeInBits() > 64)1545 return false;1546 1547 OutVTs.push_back(VT);1548 }1549 1550 Address Addr;1551 if (!computeCallAddress(Callee, Addr))1552 return false;1553 1554 // Handle the arguments now that we've gotten them.1555 unsigned NumBytes;1556 if (!processCallArgs(CLI, OutVTs, NumBytes))1557 return false;1558 1559 if (!Addr.getGlobalValue())1560 return false;1561 1562 // Issue the call.1563 unsigned DestAddress;1564 if (Symbol)1565 DestAddress = materializeExternalCallSym(Symbol);1566 else1567 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);1568 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);1569 MachineInstrBuilder MIB =1570 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::JALR),1571 Mips::RA).addReg(Mips::T9);1572 1573 // Add implicit physical register uses to the call.1574 for (auto Reg : CLI.OutRegs)1575 MIB.addReg(Reg, RegState::Implicit);1576 1577 // Add a register mask with the call-preserved registers.1578 // Proper defs for return values will be added by setPhysRegsDeadExcept().1579 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));1580 1581 CLI.Call = MIB;1582 1583 if (EmitJalrReloc && !Subtarget->inMips16Mode()) {1584 // Attach callee address to the instruction, let asm printer emit1585 // .reloc R_MIPS_JALR.1586 if (Symbol)1587 MIB.addSym(Symbol, MipsII::MO_JALR);1588 else1589 MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol(1590 Addr.getGlobalValue()->getName()), MipsII::MO_JALR);1591 }1592 1593 // Finish off the call including any return values.1594 return finishCall(CLI, RetVT, NumBytes);1595}1596 1597bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {1598 switch (II->getIntrinsicID()) {1599 default:1600 return false;1601 case Intrinsic::bswap: {1602 Type *RetTy = II->getCalledFunction()->getReturnType();1603 1604 MVT VT;1605 if (!isTypeSupported(RetTy, VT))1606 return false;1607 1608 Register SrcReg = getRegForValue(II->getOperand(0));1609 if (SrcReg == 0)1610 return false;1611 Register DestReg = createResultReg(&Mips::GPR32RegClass);1612 if (DestReg == 0)1613 return false;1614 if (VT == MVT::i16) {1615 if (Subtarget->hasMips32r2()) {1616 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);1617 updateValueMap(II, DestReg);1618 return true;1619 } else {1620 unsigned TempReg[3];1621 for (unsigned &R : TempReg) {1622 R = createResultReg(&Mips::GPR32RegClass);1623 if (R == 0)1624 return false;1625 }1626 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);1627 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);1628 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);1629 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);1630 updateValueMap(II, DestReg);1631 return true;1632 }1633 } else if (VT == MVT::i32) {1634 if (Subtarget->hasMips32r2()) {1635 Register TempReg = createResultReg(&Mips::GPR32RegClass);1636 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);1637 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);1638 updateValueMap(II, DestReg);1639 return true;1640 } else {1641 unsigned TempReg[8];1642 for (unsigned &R : TempReg) {1643 R = createResultReg(&Mips::GPR32RegClass);1644 if (R == 0)1645 return false;1646 }1647 1648 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);1649 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);1650 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);1651 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);1652 1653 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);1654 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);1655 1656 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);1657 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);1658 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);1659 updateValueMap(II, DestReg);1660 return true;1661 }1662 }1663 return false;1664 }1665 case Intrinsic::memcpy:1666 case Intrinsic::memmove: {1667 const auto *MTI = cast<MemTransferInst>(II);1668 // Don't handle volatile.1669 if (MTI->isVolatile())1670 return false;1671 if (!MTI->getLength()->getType()->isIntegerTy(32))1672 return false;1673 const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";1674 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);1675 }1676 case Intrinsic::memset: {1677 const MemSetInst *MSI = cast<MemSetInst>(II);1678 // Don't handle volatile.1679 if (MSI->isVolatile())1680 return false;1681 if (!MSI->getLength()->getType()->isIntegerTy(32))1682 return false;1683 return lowerCallTo(II, "memset", II->arg_size() - 1);1684 }1685 }1686 return false;1687}1688 1689bool MipsFastISel::selectRet(const Instruction *I) {1690 const Function &F = *I->getParent()->getParent();1691 const ReturnInst *Ret = cast<ReturnInst>(I);1692 1693 LLVM_DEBUG(dbgs() << "selectRet\n");1694 1695 if (!FuncInfo.CanLowerReturn)1696 return false;1697 1698 // Build a list of return value registers.1699 SmallVector<unsigned, 4> RetRegs;1700 1701 if (Ret->getNumOperands() > 0) {1702 CallingConv::ID CC = F.getCallingConv();1703 1704 // Do not handle FastCC.1705 if (CC == CallingConv::Fast)1706 return false;1707 1708 SmallVector<ISD::OutputArg, 4> Outs;1709 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);1710 1711 // Analyze operands of the call, assigning locations to each operand.1712 SmallVector<CCValAssign, 16> ValLocs;1713 MipsCCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs,1714 I->getContext());1715 CCAssignFn *RetCC = RetCC_Mips;1716 CCInfo.AnalyzeReturn(Outs, RetCC);1717 1718 // Only handle a single return value for now.1719 if (ValLocs.size() != 1)1720 return false;1721 1722 CCValAssign &VA = ValLocs[0];1723 const Value *RV = Ret->getOperand(0);1724 1725 // Don't bother handling odd stuff for now.1726 if ((VA.getLocInfo() != CCValAssign::Full) &&1727 (VA.getLocInfo() != CCValAssign::BCvt))1728 return false;1729 1730 // Only handle register returns for now.1731 if (!VA.isRegLoc())1732 return false;1733 1734 Register Reg = getRegForValue(RV);1735 if (Reg == 0)1736 return false;1737 1738 unsigned SrcReg = Reg + VA.getValNo();1739 Register DestReg = VA.getLocReg();1740 // Avoid a cross-class copy. This is very unlikely.1741 if (!MRI.getRegClass(SrcReg)->contains(DestReg))1742 return false;1743 1744 EVT RVEVT = TLI.getValueType(DL, RV->getType());1745 if (!RVEVT.isSimple())1746 return false;1747 1748 if (RVEVT.isVector())1749 return false;1750 1751 MVT RVVT = RVEVT.getSimpleVT();1752 if (RVVT == MVT::f128)1753 return false;1754 1755 // Do not handle FGR64 returns for now.1756 if (RVVT == MVT::f64 && UnsupportedFPMode) {1757 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");1758 return false;1759 }1760 1761 MVT DestVT = VA.getValVT();1762 // Special handling for extended integers.1763 if (RVVT != DestVT) {1764 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)1765 return false;1766 1767 if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {1768 bool IsZExt = Outs[0].Flags.isZExt();1769 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);1770 if (SrcReg == 0)1771 return false;1772 }1773 }1774 1775 // Make the copy.1776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1777 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);1778 1779 // Add register to return instruction.1780 RetRegs.push_back(VA.getLocReg());1781 }1782 MachineInstrBuilder MIB = emitInst(Mips::RetRA);1783 for (unsigned Reg : RetRegs)1784 MIB.addReg(Reg, RegState::Implicit);1785 return true;1786}1787 1788bool MipsFastISel::selectTrunc(const Instruction *I) {1789 // The high bits for a type smaller than the register size are assumed to be1790 // undefined.1791 Value *Op = I->getOperand(0);1792 1793 EVT SrcVT, DestVT;1794 SrcVT = TLI.getValueType(DL, Op->getType(), true);1795 DestVT = TLI.getValueType(DL, I->getType(), true);1796 1797 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)1798 return false;1799 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)1800 return false;1801 1802 Register SrcReg = getRegForValue(Op);1803 if (!SrcReg)1804 return false;1805 1806 // Because the high bits are undefined, a truncate doesn't generate1807 // any code.1808 updateValueMap(I, SrcReg);1809 return true;1810}1811 1812bool MipsFastISel::selectIntExt(const Instruction *I) {1813 Type *DestTy = I->getType();1814 Value *Src = I->getOperand(0);1815 Type *SrcTy = Src->getType();1816 1817 bool isZExt = isa<ZExtInst>(I);1818 Register SrcReg = getRegForValue(Src);1819 if (!SrcReg)1820 return false;1821 1822 EVT SrcEVT, DestEVT;1823 SrcEVT = TLI.getValueType(DL, SrcTy, true);1824 DestEVT = TLI.getValueType(DL, DestTy, true);1825 if (!SrcEVT.isSimple())1826 return false;1827 if (!DestEVT.isSimple())1828 return false;1829 1830 MVT SrcVT = SrcEVT.getSimpleVT();1831 MVT DestVT = DestEVT.getSimpleVT();1832 Register ResultReg = createResultReg(&Mips::GPR32RegClass);1833 1834 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))1835 return false;1836 updateValueMap(I, ResultReg);1837 return true;1838}1839 1840bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,1841 unsigned DestReg) {1842 unsigned ShiftAmt;1843 switch (SrcVT.SimpleTy) {1844 default:1845 return false;1846 case MVT::i8:1847 ShiftAmt = 24;1848 break;1849 case MVT::i16:1850 ShiftAmt = 16;1851 break;1852 }1853 Register TempReg = createResultReg(&Mips::GPR32RegClass);1854 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);1855 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);1856 return true;1857}1858 1859bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,1860 unsigned DestReg) {1861 switch (SrcVT.SimpleTy) {1862 default:1863 return false;1864 case MVT::i8:1865 emitInst(Mips::SEB, DestReg).addReg(SrcReg);1866 break;1867 case MVT::i16:1868 emitInst(Mips::SEH, DestReg).addReg(SrcReg);1869 break;1870 }1871 return true;1872}1873 1874bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1875 unsigned DestReg) {1876 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))1877 return false;1878 if (Subtarget->hasMips32r2())1879 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);1880 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);1881}1882 1883bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1884 unsigned DestReg) {1885 int64_t Imm;1886 1887 switch (SrcVT.SimpleTy) {1888 default:1889 return false;1890 case MVT::i1:1891 Imm = 1;1892 break;1893 case MVT::i8:1894 Imm = 0xff;1895 break;1896 case MVT::i16:1897 Imm = 0xffff;1898 break;1899 }1900 1901 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);1902 return true;1903}1904 1905bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1906 unsigned DestReg, bool IsZExt) {1907 // FastISel does not have plumbing to deal with extensions where the SrcVT or1908 // DestVT are odd things, so test to make sure that they are both types we can1909 // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise1910 // bail out to SelectionDAG.1911 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||1912 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))1913 return false;1914 if (IsZExt)1915 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);1916 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);1917}1918 1919unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1920 bool isZExt) {1921 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);1922 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);1923 return Success ? DestReg : 0;1924}1925 1926bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {1927 EVT DestEVT = TLI.getValueType(DL, I->getType(), true);1928 if (!DestEVT.isSimple())1929 return false;1930 1931 MVT DestVT = DestEVT.getSimpleVT();1932 if (DestVT != MVT::i32)1933 return false;1934 1935 unsigned DivOpc;1936 switch (ISDOpcode) {1937 default:1938 return false;1939 case ISD::SDIV:1940 case ISD::SREM:1941 DivOpc = Mips::SDIV;1942 break;1943 case ISD::UDIV:1944 case ISD::UREM:1945 DivOpc = Mips::UDIV;1946 break;1947 }1948 1949 Register Src0Reg = getRegForValue(I->getOperand(0));1950 Register Src1Reg = getRegForValue(I->getOperand(1));1951 if (!Src0Reg || !Src1Reg)1952 return false;1953 1954 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);1955 if (!isa<ConstantInt>(I->getOperand(1)) ||1956 dyn_cast<ConstantInt>(I->getOperand(1))->isZero()) {1957 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);1958 }1959 1960 Register ResultReg = createResultReg(&Mips::GPR32RegClass);1961 if (!ResultReg)1962 return false;1963 1964 unsigned MFOpc = (ISDOpcode == ISD::SREM || ISDOpcode == ISD::UREM)1965 ? Mips::MFHI1966 : Mips::MFLO;1967 emitInst(MFOpc, ResultReg);1968 1969 updateValueMap(I, ResultReg);1970 return true;1971}1972 1973bool MipsFastISel::selectShift(const Instruction *I) {1974 MVT RetVT;1975 1976 if (!isTypeSupported(I->getType(), RetVT))1977 return false;1978 1979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);1980 if (!ResultReg)1981 return false;1982 1983 unsigned Opcode = I->getOpcode();1984 const Value *Op0 = I->getOperand(0);1985 Register Op0Reg = getRegForValue(Op0);1986 if (!Op0Reg)1987 return false;1988 1989 // If AShr or LShr, then we need to make sure the operand0 is sign extended.1990 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {1991 Register TempReg = createResultReg(&Mips::GPR32RegClass);1992 if (!TempReg)1993 return false;1994 1995 MVT Op0MVT = TLI.getValueType(DL, Op0->getType(), true).getSimpleVT();1996 bool IsZExt = Opcode == Instruction::LShr;1997 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))1998 return false;1999 2000 Op0Reg = TempReg;2001 }2002 2003 if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {2004 uint64_t ShiftVal = C->getZExtValue();2005 2006 switch (Opcode) {2007 default:2008 llvm_unreachable("Unexpected instruction.");2009 case Instruction::Shl:2010 Opcode = Mips::SLL;2011 break;2012 case Instruction::AShr:2013 Opcode = Mips::SRA;2014 break;2015 case Instruction::LShr:2016 Opcode = Mips::SRL;2017 break;2018 }2019 2020 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);2021 updateValueMap(I, ResultReg);2022 return true;2023 }2024 2025 Register Op1Reg = getRegForValue(I->getOperand(1));2026 if (!Op1Reg)2027 return false;2028 2029 switch (Opcode) {2030 default:2031 llvm_unreachable("Unexpected instruction.");2032 case Instruction::Shl:2033 Opcode = Mips::SLLV;2034 break;2035 case Instruction::AShr:2036 Opcode = Mips::SRAV;2037 break;2038 case Instruction::LShr:2039 Opcode = Mips::SRLV;2040 break;2041 }2042 2043 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);2044 updateValueMap(I, ResultReg);2045 return true;2046}2047 2048bool MipsFastISel::fastSelectInstruction(const Instruction *I) {2049 switch (I->getOpcode()) {2050 default:2051 break;2052 case Instruction::Load:2053 return selectLoad(I);2054 case Instruction::Store:2055 return selectStore(I);2056 case Instruction::SDiv:2057 if (!selectBinaryOp(I, ISD::SDIV))2058 return selectDivRem(I, ISD::SDIV);2059 return true;2060 case Instruction::UDiv:2061 if (!selectBinaryOp(I, ISD::UDIV))2062 return selectDivRem(I, ISD::UDIV);2063 return true;2064 case Instruction::SRem:2065 if (!selectBinaryOp(I, ISD::SREM))2066 return selectDivRem(I, ISD::SREM);2067 return true;2068 case Instruction::URem:2069 if (!selectBinaryOp(I, ISD::UREM))2070 return selectDivRem(I, ISD::UREM);2071 return true;2072 case Instruction::Shl:2073 case Instruction::LShr:2074 case Instruction::AShr:2075 return selectShift(I);2076 case Instruction::And:2077 case Instruction::Or:2078 case Instruction::Xor:2079 return selectLogicalOp(I);2080 case Instruction::Br:2081 return selectBranch(I);2082 case Instruction::Ret:2083 return selectRet(I);2084 case Instruction::Trunc:2085 return selectTrunc(I);2086 case Instruction::ZExt:2087 case Instruction::SExt:2088 return selectIntExt(I);2089 case Instruction::FPTrunc:2090 return selectFPTrunc(I);2091 case Instruction::FPExt:2092 return selectFPExt(I);2093 case Instruction::FPToSI:2094 return selectFPToInt(I, /*isSigned*/ true);2095 case Instruction::FPToUI:2096 return selectFPToInt(I, /*isSigned*/ false);2097 case Instruction::ICmp:2098 case Instruction::FCmp:2099 return selectCmp(I);2100 case Instruction::Select:2101 return selectSelect(I);2102 }2103 return false;2104}2105 2106unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,2107 bool IsUnsigned) {2108 Register VReg = getRegForValue(V);2109 if (VReg == 0)2110 return 0;2111 MVT VMVT = TLI.getValueType(DL, V->getType(), true).getSimpleVT();2112 2113 if (VMVT == MVT::i1)2114 return 0;2115 2116 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {2117 Register TempReg = createResultReg(&Mips::GPR32RegClass);2118 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))2119 return 0;2120 VReg = TempReg;2121 }2122 return VReg;2123}2124 2125void MipsFastISel::simplifyAddress(Address &Addr) {2126 if (!isInt<16>(Addr.getOffset())) {2127 unsigned TempReg =2128 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);2129 Register DestReg = createResultReg(&Mips::GPR32RegClass);2130 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());2131 Addr.setReg(DestReg);2132 Addr.setOffset(0);2133 }2134}2135 2136unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,2137 const TargetRegisterClass *RC,2138 unsigned Op0, unsigned Op1) {2139 // We treat the MUL instruction in a special way because it clobbers2140 // the HI0 & LO0 registers. The TableGen definition of this instruction can2141 // mark these registers only as implicitly defined. As a result, the2142 // register allocator runs out of registers when this instruction is2143 // followed by another instruction that defines the same registers too.2144 // We can fix this by explicitly marking those registers as dead.2145 if (MachineInstOpcode == Mips::MUL) {2146 Register ResultReg = createResultReg(RC);2147 const MCInstrDesc &II = TII.get(MachineInstOpcode);2148 Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());2149 Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);2150 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)2151 .addReg(Op0)2152 .addReg(Op1)2153 .addReg(Mips::HI0, RegState::ImplicitDefine | RegState::Dead)2154 .addReg(Mips::LO0, RegState::ImplicitDefine | RegState::Dead);2155 return ResultReg;2156 }2157 2158 return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op1);2159}2160 2161namespace llvm {2162 2163FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,2164 const TargetLibraryInfo *libInfo) {2165 return new MipsFastISel(funcInfo, libInfo);2166}2167 2168} // end namespace llvm2169