LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMRegisterBankInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 103 109 94.5 %
Date: 2018-06-17 00:07:59 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This file implements the targeting of the RegisterBankInfo class for ARM.
      11             : /// \todo This should be generated by TableGen.
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "ARMRegisterBankInfo.h"
      15             : #include "ARMInstrInfo.h" // For the register classes
      16             : #include "ARMSubtarget.h"
      17             : #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
      18             : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
      19             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      20             : #include "llvm/CodeGen/TargetRegisterInfo.h"
      21             : 
      22             : #define GET_TARGET_REGBANK_IMPL
      23             : #include "ARMGenRegisterBank.inc"
      24             : 
      25             : using namespace llvm;
      26             : 
      27             : // FIXME: TableGen this.
      28             : // If it grows too much and TableGen still isn't ready to do the job, extract it
      29             : // into an ARMGenRegisterBankInfo.def (similar to AArch64).
      30             : namespace llvm {
      31             : namespace ARM {
      32             : enum PartialMappingIdx {
      33             :   PMI_GPR,
      34             :   PMI_SPR,
      35             :   PMI_DPR,
      36             :   PMI_Min = PMI_GPR,
      37             : };
      38             : 
      39             : RegisterBankInfo::PartialMapping PartMappings[]{
      40             :     // GPR Partial Mapping
      41             :     {0, 32, GPRRegBank},
      42             :     // SPR Partial Mapping
      43             :     {0, 32, FPRRegBank},
      44             :     // DPR Partial Mapping
      45             :     {0, 64, FPRRegBank},
      46             : };
      47             : 
      48             : #ifndef NDEBUG
      49             : static bool checkPartMapping(const RegisterBankInfo::PartialMapping &PM,
      50             :                              unsigned Start, unsigned Length,
      51             :                              unsigned RegBankID) {
      52             :   return PM.StartIdx == Start && PM.Length == Length &&
      53             :          PM.RegBank->getID() == RegBankID;
      54             : }
      55             : 
      56             : static void checkPartialMappings() {
      57             :   assert(
      58             :       checkPartMapping(PartMappings[PMI_GPR - PMI_Min], 0, 32, GPRRegBankID) &&
      59             :       "Wrong mapping for GPR");
      60             :   assert(
      61             :       checkPartMapping(PartMappings[PMI_SPR - PMI_Min], 0, 32, FPRRegBankID) &&
      62             :       "Wrong mapping for SPR");
      63             :   assert(
      64             :       checkPartMapping(PartMappings[PMI_DPR - PMI_Min], 0, 64, FPRRegBankID) &&
      65             :       "Wrong mapping for DPR");
      66             : }
      67             : #endif
      68             : 
      69             : enum ValueMappingIdx {
      70             :   InvalidIdx = 0,
      71             :   GPR3OpsIdx = 1,
      72             :   SPR3OpsIdx = 4,
      73             :   DPR3OpsIdx = 7,
      74             : };
      75             : 
      76             : RegisterBankInfo::ValueMapping ValueMappings[] = {
      77             :     // invalid
      78             :     {nullptr, 0},
      79             :     // 3 ops in GPRs
      80             :     {&PartMappings[PMI_GPR - PMI_Min], 1},
      81             :     {&PartMappings[PMI_GPR - PMI_Min], 1},
      82             :     {&PartMappings[PMI_GPR - PMI_Min], 1},
      83             :     // 3 ops in SPRs
      84             :     {&PartMappings[PMI_SPR - PMI_Min], 1},
      85             :     {&PartMappings[PMI_SPR - PMI_Min], 1},
      86             :     {&PartMappings[PMI_SPR - PMI_Min], 1},
      87             :     // 3 ops in DPRs
      88             :     {&PartMappings[PMI_DPR - PMI_Min], 1},
      89             :     {&PartMappings[PMI_DPR - PMI_Min], 1},
      90             :     {&PartMappings[PMI_DPR - PMI_Min], 1}};
      91             : 
      92             : #ifndef NDEBUG
      93             : static bool checkValueMapping(const RegisterBankInfo::ValueMapping &VM,
      94             :                               RegisterBankInfo::PartialMapping *BreakDown) {
      95             :   return VM.NumBreakDowns == 1 && VM.BreakDown == BreakDown;
      96             : }
      97             : 
      98             : static void checkValueMappings() {
      99             :   assert(checkValueMapping(ValueMappings[GPR3OpsIdx],
     100             :                            &PartMappings[PMI_GPR - PMI_Min]) &&
     101             :          "Wrong value mapping for 3 GPR ops instruction");
     102             :   assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 1],
     103             :                            &PartMappings[PMI_GPR - PMI_Min]) &&
     104             :          "Wrong value mapping for 3 GPR ops instruction");
     105             :   assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 2],
     106             :                            &PartMappings[PMI_GPR - PMI_Min]) &&
     107             :          "Wrong value mapping for 3 GPR ops instruction");
     108             : 
     109             :   assert(checkValueMapping(ValueMappings[SPR3OpsIdx],
     110             :                            &PartMappings[PMI_SPR - PMI_Min]) &&
     111             :          "Wrong value mapping for 3 SPR ops instruction");
     112             :   assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 1],
     113             :                            &PartMappings[PMI_SPR - PMI_Min]) &&
     114             :          "Wrong value mapping for 3 SPR ops instruction");
     115             :   assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 2],
     116             :                            &PartMappings[PMI_SPR - PMI_Min]) &&
     117             :          "Wrong value mapping for 3 SPR ops instruction");
     118             : 
     119             :   assert(checkValueMapping(ValueMappings[DPR3OpsIdx],
     120             :                            &PartMappings[PMI_DPR - PMI_Min]) &&
     121             :          "Wrong value mapping for 3 DPR ops instruction");
     122             :   assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 1],
     123             :                            &PartMappings[PMI_DPR - PMI_Min]) &&
     124             :          "Wrong value mapping for 3 DPR ops instruction");
     125             :   assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 2],
     126             :                            &PartMappings[PMI_DPR - PMI_Min]) &&
     127             :          "Wrong value mapping for 3 DPR ops instruction");
     128             : }
     129             : #endif
     130             : } // end namespace arm
     131             : } // end namespace llvm
     132             : 
     133        4804 : ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI)
     134        4804 :     : ARMGenRegisterBankInfo() {
     135             :   static bool AlreadyInit = false;
     136             :   // We have only one set of register banks, whatever the subtarget
     137             :   // is. Therefore, the initialization of the RegBanks table should be
     138             :   // done only once. Indeed the table of all register banks
     139             :   // (ARM::RegBanks) is unique in the compiler. At some point, it
     140             :   // will get tablegen'ed and the whole constructor becomes empty.
     141        4804 :   if (AlreadyInit)
     142             :     return;
     143        2891 :   AlreadyInit = true;
     144             : 
     145             :   const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
     146             :   (void)RBGPR;
     147             :   assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");
     148             : 
     149             :   // Initialize the GPR bank.
     150             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) &&
     151             :          "Subclass not added?");
     152             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) &&
     153             :          "Subclass not added?");
     154             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) &&
     155             :          "Subclass not added?");
     156             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) &&
     157             :          "Subclass not added?");
     158             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) &&
     159             :          "Subclass not added?");
     160             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
     161             :          "Subclass not added?");
     162             :   assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) &&
     163             :          "Subclass not added?");
     164             :   assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
     165             : 
     166             : #ifndef NDEBUG
     167             :   ARM::checkPartialMappings();
     168             :   ARM::checkValueMappings();
     169             : #endif
     170             : }
     171             : 
     172        3126 : const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass(
     173             :     const TargetRegisterClass &RC) const {
     174             :   using namespace ARM;
     175             : 
     176        3126 :   switch (RC.getID()) {
     177        2759 :   case GPRRegClassID:
     178             :   case GPRwithAPSRRegClassID:
     179             :   case GPRnopcRegClassID:
     180             :   case rGPRRegClassID:
     181             :   case GPRspRegClassID:
     182             :   case tGPR_and_tcGPRRegClassID:
     183             :   case tcGPRRegClassID:
     184             :   case tGPRRegClassID:
     185        2759 :     return getRegBank(ARM::GPRRegBankID);
     186         367 :   case HPRRegClassID:
     187             :   case SPR_8RegClassID:
     188             :   case SPRRegClassID:
     189             :   case DPR_8RegClassID:
     190             :   case DPRRegClassID:
     191             :   case QPRRegClassID:
     192         367 :     return getRegBank(ARM::FPRRegBankID);
     193           0 :   default:
     194           0 :     llvm_unreachable("Unsupported register kind");
     195             :   }
     196             : 
     197             :   llvm_unreachable("Switch should handle all register classes");
     198             : }
     199             : 
     200             : const RegisterBankInfo::InstructionMapping &
     201        1460 : ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     202        1460 :   auto Opc = MI.getOpcode();
     203             : 
     204             :   // Try the default logic for non-generic instructions that are either copies
     205             :   // or already have some operands assigned to banks.
     206        1460 :   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
     207         933 :     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
     208             :     if (Mapping.isValid())
     209             :       return Mapping;
     210             :   }
     211             : 
     212             :   using namespace TargetOpcode;
     213             : 
     214         527 :   const MachineFunction &MF = *MI.getParent()->getParent();
     215         527 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     216         527 :   unsigned NumOperands = MI.getNumOperands();
     217             :   const ValueMapping *OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx];
     218             : 
     219         527 :   switch (Opc) {
     220             :   case G_ADD:
     221             :   case G_SUB:
     222             :   case G_MUL:
     223             :   case G_AND:
     224             :   case G_OR:
     225             :   case G_XOR:
     226             :   case G_LSHR:
     227             :   case G_ASHR:
     228             :   case G_SHL:
     229             :   case G_SDIV:
     230             :   case G_UDIV:
     231             :   case G_SEXT:
     232             :   case G_ZEXT:
     233             :   case G_ANYEXT:
     234             :   case G_GEP:
     235             :   case G_INTTOPTR:
     236             :   case G_PTRTOINT:
     237             :     // FIXME: We're abusing the fact that everything lives in a GPR for now; in
     238             :     // the real world we would use different mappings.
     239             :     OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx];
     240             :     break;
     241          15 :   case G_TRUNC: {
     242             :     // In some cases we may end up with a G_TRUNC from a 64-bit value to a
     243             :     // 32-bit value. This isn't a real floating point trunc (that would be a
     244             :     // G_FPTRUNC). Instead it is an integer trunc in disguise, which can appear
     245             :     // because the legalizer doesn't distinguish between integer and floating
     246             :     // point values so it may leave some 64-bit integers un-narrowed. Until we
     247             :     // have a more principled solution that doesn't let such things sneak all
     248             :     // the way to this point, just map the source to a DPR and the destination
     249             :     // to a GPR.
     250          30 :     LLT LargeTy = MRI.getType(MI.getOperand(1).getReg());
     251             :     OperandsMapping =
     252          15 :         LargeTy.getSizeInBits() <= 32
     253          16 :             ? &ARM::ValueMappings[ARM::GPR3OpsIdx]
     254           1 :             : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
     255             :                                   &ARM::ValueMappings[ARM::DPR3OpsIdx]});
     256             :     break;
     257             :   }
     258          80 :   case G_LOAD:
     259             :   case G_STORE: {
     260         160 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     261             :     OperandsMapping =
     262          80 :         Ty.getSizeInBits() == 64
     263          80 :             ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
     264             :                                   &ARM::ValueMappings[ARM::GPR3OpsIdx]})
     265             :             : &ARM::ValueMappings[ARM::GPR3OpsIdx];
     266             :     break;
     267             :   }
     268          18 :   case G_FADD:
     269             :   case G_FSUB:
     270             :   case G_FMUL:
     271             :   case G_FDIV:
     272             :   case G_FNEG: {
     273          36 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     274          18 :     OperandsMapping =Ty.getSizeInBits() == 64
     275             :                           ? &ARM::ValueMappings[ARM::DPR3OpsIdx]
     276             :                           : &ARM::ValueMappings[ARM::SPR3OpsIdx];
     277             :     break;
     278             :   }
     279           2 :   case G_FMA: {
     280           4 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     281             :     OperandsMapping =
     282           2 :         Ty.getSizeInBits() == 64
     283           3 :             ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
     284             :                                   &ARM::ValueMappings[ARM::DPR3OpsIdx],
     285             :                                   &ARM::ValueMappings[ARM::DPR3OpsIdx],
     286             :                                   &ARM::ValueMappings[ARM::DPR3OpsIdx]})
     287           1 :             : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
     288             :                                   &ARM::ValueMappings[ARM::SPR3OpsIdx],
     289             :                                   &ARM::ValueMappings[ARM::SPR3OpsIdx],
     290             :                                   &ARM::ValueMappings[ARM::SPR3OpsIdx]});
     291             :     break;
     292             :   }
     293           1 :   case G_FPEXT: {
     294           2 :     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
     295           2 :     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
     296           1 :     if (ToTy.getSizeInBits() == 64 && FromTy.getSizeInBits() == 32)
     297           1 :       OperandsMapping =
     298           1 :           getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
     299             :                               &ARM::ValueMappings[ARM::SPR3OpsIdx]});
     300             :     break;
     301             :   }
     302           1 :   case G_FPTRUNC: {
     303           2 :     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
     304           2 :     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
     305           1 :     if (ToTy.getSizeInBits() == 32 && FromTy.getSizeInBits() == 64)
     306           1 :       OperandsMapping =
     307           1 :           getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
     308             :                               &ARM::ValueMappings[ARM::DPR3OpsIdx]});
     309             :     break;
     310             :   }
     311           4 :   case G_FPTOSI:
     312             :   case G_FPTOUI: {
     313           8 :     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
     314           8 :     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
     315           8 :     if ((FromTy.getSizeInBits() == 32 || FromTy.getSizeInBits() == 64) &&
     316           4 :         ToTy.getSizeInBits() == 32)
     317             :       OperandsMapping =
     318             :           FromTy.getSizeInBits() == 64
     319           6 :               ? getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
     320             :                                     &ARM::ValueMappings[ARM::DPR3OpsIdx]})
     321           2 :               : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
     322             :                                     &ARM::ValueMappings[ARM::SPR3OpsIdx]});
     323             :     break;
     324             :   }
     325           4 :   case G_SITOFP:
     326             :   case G_UITOFP: {
     327           8 :     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
     328           8 :     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
     329           8 :     if (FromTy.getSizeInBits() == 32 &&
     330           6 :         (ToTy.getSizeInBits() == 32 || ToTy.getSizeInBits() == 64))
     331             :       OperandsMapping =
     332             :           ToTy.getSizeInBits() == 64
     333           6 :               ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
     334             :                                     &ARM::ValueMappings[ARM::GPR3OpsIdx]})
     335           2 :               : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
     336             :                                     &ARM::ValueMappings[ARM::GPR3OpsIdx]});
     337             :     break;
     338             :   }
     339         144 :   case G_CONSTANT:
     340             :   case G_FRAME_INDEX:
     341             :   case G_GLOBAL_VALUE:
     342         144 :     OperandsMapping =
     343         144 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
     344         144 :     break;
     345             :   case G_SELECT: {
     346             :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     347             :     (void)Ty;
     348             :     LLT Ty2 = MRI.getType(MI.getOperand(1).getReg());
     349             :     (void)Ty2;
     350             :     assert(Ty.getSizeInBits() == 32 && "Unsupported size for G_SELECT");
     351             :     assert(Ty2.getSizeInBits() == 1 && "Unsupported size for G_SELECT");
     352           3 :     OperandsMapping =
     353           3 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
     354             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
     355             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
     356             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
     357             :     break;
     358             :   }
     359             :   case G_ICMP: {
     360             :     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
     361             :     (void)Ty2;
     362             :     assert(Ty2.getSizeInBits() == 32 && "Unsupported size for G_ICMP");
     363           8 :     OperandsMapping =
     364           8 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
     365             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
     366             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
     367             :     break;
     368             :   }
     369           4 :   case G_FCMP: {
     370           4 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     371             :     (void)Ty;
     372           8 :     LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
     373             :     LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
     374             :     (void)Ty2;
     375             :     assert(Ty.getSizeInBits() == 1 && "Unsupported size for G_FCMP");
     376             :     assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
     377             :            "Mismatched operand sizes for G_FCMP");
     378             : 
     379           4 :     unsigned Size = Ty1.getSizeInBits();
     380             :     assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
     381             : 
     382           4 :     auto FPRValueMapping = Size == 32 ? &ARM::ValueMappings[ARM::SPR3OpsIdx]
     383             :                                       : &ARM::ValueMappings[ARM::DPR3OpsIdx];
     384           4 :     OperandsMapping =
     385           8 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
     386             :                             FPRValueMapping, FPRValueMapping});
     387             :     break;
     388             :   }
     389          11 :   case G_MERGE_VALUES: {
     390             :     // We only support G_MERGE_VALUES for creating a double precision floating
     391             :     // point value out of two GPRs.
     392          22 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     393          22 :     LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
     394          22 :     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
     395          22 :     if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 ||
     396          11 :         Ty2.getSizeInBits() != 32)
     397           0 :       return getInvalidInstructionMapping();
     398          11 :     OperandsMapping =
     399          11 :         getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
     400             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
     401             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
     402          11 :     break;
     403             :   }
     404           6 :   case G_UNMERGE_VALUES: {
     405             :     // We only support G_UNMERGE_VALUES for splitting a double precision
     406             :     // floating point value into two GPRs.
     407          12 :     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
     408          12 :     LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
     409          12 :     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
     410          12 :     if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 32 ||
     411           6 :         Ty2.getSizeInBits() != 64)
     412           0 :       return getInvalidInstructionMapping();
     413           6 :     OperandsMapping =
     414           6 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
     415             :                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
     416             :                             &ARM::ValueMappings[ARM::DPR3OpsIdx]});
     417           6 :     break;
     418             :   }
     419           6 :   case G_BR:
     420           6 :     OperandsMapping = getOperandsMapping({nullptr});
     421           6 :     break;
     422           4 :   case G_BRCOND:
     423           4 :     OperandsMapping =
     424           4 :         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
     425           4 :     break;
     426           0 :   default:
     427           0 :     return getInvalidInstructionMapping();
     428             :   }
     429             : 
     430             : #ifndef NDEBUG
     431             :   for (unsigned i = 0; i < NumOperands; i++) {
     432             :     for (const auto &Mapping : OperandsMapping[i]) {
     433             :       assert(
     434             :           (Mapping.RegBank->getID() != ARM::FPRRegBankID ||
     435             :            MF.getSubtarget<ARMSubtarget>().hasVFP2()) &&
     436             :           "Trying to use floating point register bank on target without vfp");
     437             :     }
     438             :   }
     439             : #endif
     440             : 
     441             :   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
     442        1054 :                                NumOperands);
     443      303507 : }

Generated by: LCOV version 1.13