003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/ARM
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
ARM
/
📁
..
📄
A15SDOptimizer.cpp
(24.01 KB)
📄
ARM.h
(2.78 KB)
📄
ARM.td
(73.6 KB)
📄
ARMAsmPrinter.cpp
(80.17 KB)
📄
ARMAsmPrinter.h
(5.74 KB)
📄
ARMBaseInstrInfo.cpp
(209.03 KB)
📄
ARMBaseInstrInfo.h
(36.07 KB)
📄
ARMBaseRegisterInfo.cpp
(34.2 KB)
📄
ARMBaseRegisterInfo.h
(7.84 KB)
📄
ARMBasicBlockInfo.cpp
(5.18 KB)
📄
ARMBasicBlockInfo.h
(5.25 KB)
📄
ARMCallLowering.cpp
(19.74 KB)
📄
ARMCallLowering.h
(1.89 KB)
📄
ARMCallingConv.cpp
(11.8 KB)
📄
ARMCallingConv.h
(2.43 KB)
📄
ARMCallingConv.td
(14.63 KB)
📄
ARMConstantIslandPass.cpp
(90.84 KB)
📄
ARMConstantPoolValue.cpp
(11.53 KB)
📄
ARMConstantPoolValue.h
(10.1 KB)
📄
ARMExpandPseudoInsts.cpp
(115.56 KB)
📄
ARMFastISel.cpp
(106.14 KB)
📄
ARMFeatures.h
(2.48 KB)
📄
ARMFrameLowering.cpp
(102.32 KB)
📄
ARMFrameLowering.h
(4.02 KB)
📄
ARMHazardRecognizer.cpp
(3.41 KB)
📄
ARMHazardRecognizer.h
(1.54 KB)
📄
ARMISelDAGToDAG.cpp
(206.42 KB)
📄
ARMISelLowering.cpp
(728.6 KB)
📄
ARMISelLowering.h
(38.98 KB)
📄
ARMInstrCDE.td
(24.04 KB)
📄
ARMInstrFormats.td
(93.92 KB)
📄
ARMInstrInfo.cpp
(4.2 KB)
📄
ARMInstrInfo.h
(1.49 KB)
📄
ARMInstrInfo.td
(243.51 KB)
📄
ARMInstrMVE.td
(299.67 KB)
📄
ARMInstrNEON.td
(436.25 KB)
📄
ARMInstrThumb.td
(65.92 KB)
📄
ARMInstrThumb2.td
(211.06 KB)
📄
ARMInstrVFP.td
(110.46 KB)
📄
ARMInstructionSelector.cpp
(39.12 KB)
📄
ARMLegalizerInfo.cpp
(18.8 KB)
📄
ARMLegalizerInfo.h
(2.41 KB)
📄
ARMLoadStoreOptimizer.cpp
(94.44 KB)
📄
ARMLowOverheadLoops.cpp
(60.28 KB)
📄
ARMMCInstLower.cpp
(7.2 KB)
📄
ARMMachineFunctionInfo.cpp
(821 B)
📄
ARMMachineFunctionInfo.h
(9.68 KB)
📄
ARMMacroFusion.cpp
(2.36 KB)
📄
ARMMacroFusion.h
(966 B)
📄
ARMOptimizeBarriersPass.cpp
(3.43 KB)
📄
ARMParallelDSP.cpp
(26.82 KB)
📄
ARMPerfectShuffle.h
(382.02 KB)
📄
ARMPredicates.td
(14.16 KB)
📄
ARMRegisterBankInfo.cpp
(18.18 KB)
📄
ARMRegisterBankInfo.h
(1.41 KB)
📄
ARMRegisterBanks.td
(577 B)
📄
ARMRegisterInfo.cpp
(685 B)
📄
ARMRegisterInfo.h
(845 B)
📄
ARMRegisterInfo.td
(24.53 KB)
📄
ARMSchedule.td
(15.13 KB)
📄
ARMScheduleA57.td
(62.61 KB)
📄
ARMScheduleA57WriteRes.td
(11.43 KB)
📄
ARMScheduleA8.td
(49.59 KB)
📄
ARMScheduleA9.td
(130.35 KB)
📄
ARMScheduleM4.td
(4.77 KB)
📄
ARMScheduleR52.td
(44.27 KB)
📄
ARMScheduleSwift.td
(50.53 KB)
📄
ARMScheduleV6.td
(12.34 KB)
📄
ARMSelectionDAGInfo.cpp
(9.21 KB)
📄
ARMSelectionDAGInfo.h
(2.81 KB)
📄
ARMSubtarget.cpp
(16.73 KB)
📄
ARMSubtarget.h
(31.56 KB)
📄
ARMSystemRegister.td
(5.42 KB)
📄
ARMTargetMachine.cpp
(19.74 KB)
📄
ARMTargetMachine.h
(3.48 KB)
📄
ARMTargetObjectFile.cpp
(3.75 KB)
📄
ARMTargetObjectFile.h
(1.67 KB)
📄
ARMTargetTransformInfo.cpp
(63.49 KB)
📄
ARMTargetTransformInfo.h
(10.22 KB)
📁
AsmParser
📁
Disassembler
📁
MCTargetDesc
📄
MLxExpansionPass.cpp
(11.56 KB)
📄
MVEGatherScatterLowering.cpp
(40.3 KB)
📄
MVETailPredication.cpp
(23.2 KB)
📄
MVEVPTBlockPass.cpp
(10.77 KB)
📄
MVEVPTOptimisationsPass.cpp
(16.46 KB)
📁
TargetInfo
📄
Thumb1FrameLowering.cpp
(39.45 KB)
📄
Thumb1FrameLowering.h
(3.48 KB)
📄
Thumb1InstrInfo.cpp
(5.73 KB)
📄
Thumb1InstrInfo.h
(2.38 KB)
📄
Thumb2ITBlockPass.cpp
(9.09 KB)
📄
Thumb2InstrInfo.cpp
(26.43 KB)
📄
Thumb2InstrInfo.h
(3.75 KB)
📄
Thumb2SizeReduction.cpp
(40.25 KB)
📄
ThumbRegisterInfo.cpp
(21.75 KB)
📄
ThumbRegisterInfo.h
(2.44 KB)
📁
Utils
Editing: ARMRegisterBankInfo.cpp
//===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file implements the targeting of the RegisterBankInfo class for ARM. /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// #include "ARMRegisterBankInfo.h" #include "ARMInstrInfo.h" // For the register classes #include "ARMSubtarget.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #define GET_TARGET_REGBANK_IMPL #include "ARMGenRegisterBank.inc" using namespace llvm; // FIXME: TableGen this. // If it grows too much and TableGen still isn't ready to do the job, extract it // into an ARMGenRegisterBankInfo.def (similar to AArch64). namespace llvm { namespace ARM { enum PartialMappingIdx { PMI_GPR, PMI_SPR, PMI_DPR, PMI_Min = PMI_GPR, }; RegisterBankInfo::PartialMapping PartMappings[]{ // GPR Partial Mapping {0, 32, GPRRegBank}, // SPR Partial Mapping {0, 32, FPRRegBank}, // DPR Partial Mapping {0, 64, FPRRegBank}, }; #ifndef NDEBUG static bool checkPartMapping(const RegisterBankInfo::PartialMapping &PM, unsigned Start, unsigned Length, unsigned RegBankID) { return PM.StartIdx == Start && PM.Length == Length && PM.RegBank->getID() == RegBankID; } static void checkPartialMappings() { assert( checkPartMapping(PartMappings[PMI_GPR - PMI_Min], 0, 32, GPRRegBankID) && "Wrong mapping for GPR"); assert( checkPartMapping(PartMappings[PMI_SPR - PMI_Min], 0, 32, FPRRegBankID) && "Wrong mapping for SPR"); assert( checkPartMapping(PartMappings[PMI_DPR - PMI_Min], 0, 64, FPRRegBankID) && "Wrong mapping for DPR"); } #endif enum ValueMappingIdx { InvalidIdx = 0, GPR3OpsIdx = 1, SPR3OpsIdx = 4, DPR3OpsIdx = 7, }; RegisterBankInfo::ValueMapping ValueMappings[] = { // invalid {nullptr, 0}, // 3 ops in GPRs {&PartMappings[PMI_GPR - PMI_Min], 1}, {&PartMappings[PMI_GPR - PMI_Min], 1}, {&PartMappings[PMI_GPR - PMI_Min], 1}, // 3 ops in SPRs {&PartMappings[PMI_SPR - PMI_Min], 1}, {&PartMappings[PMI_SPR - PMI_Min], 1}, {&PartMappings[PMI_SPR - PMI_Min], 1}, // 3 ops in DPRs {&PartMappings[PMI_DPR - PMI_Min], 1}, {&PartMappings[PMI_DPR - PMI_Min], 1}, {&PartMappings[PMI_DPR - PMI_Min], 1}}; #ifndef NDEBUG static bool checkValueMapping(const RegisterBankInfo::ValueMapping &VM, RegisterBankInfo::PartialMapping *BreakDown) { return VM.NumBreakDowns == 1 && VM.BreakDown == BreakDown; } static void checkValueMappings() { assert(checkValueMapping(ValueMappings[GPR3OpsIdx], &PartMappings[PMI_GPR - PMI_Min]) && "Wrong value mapping for 3 GPR ops instruction"); assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 1], &PartMappings[PMI_GPR - PMI_Min]) && "Wrong value mapping for 3 GPR ops instruction"); assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 2], &PartMappings[PMI_GPR - PMI_Min]) && "Wrong value mapping for 3 GPR ops instruction"); assert(checkValueMapping(ValueMappings[SPR3OpsIdx], &PartMappings[PMI_SPR - PMI_Min]) && "Wrong value mapping for 3 SPR ops instruction"); assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 1], &PartMappings[PMI_SPR - PMI_Min]) && "Wrong value mapping for 3 SPR ops instruction"); assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 2], &PartMappings[PMI_SPR - PMI_Min]) && "Wrong value mapping for 3 SPR ops instruction"); assert(checkValueMapping(ValueMappings[DPR3OpsIdx], &PartMappings[PMI_DPR - PMI_Min]) && "Wrong value mapping for 3 DPR ops instruction"); assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 1], &PartMappings[PMI_DPR - PMI_Min]) && "Wrong value mapping for 3 DPR ops instruction"); assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 2], &PartMappings[PMI_DPR - PMI_Min]) && "Wrong value mapping for 3 DPR ops instruction"); } #endif } // end namespace arm } // end namespace llvm ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) : ARMGenRegisterBankInfo() { // We have only one set of register banks, whatever the subtarget // is. Therefore, the initialization of the RegBanks table should be // done only once. Indeed the table of all register banks // (ARM::RegBanks) is unique in the compiler. At some point, it // will get tablegen'ed and the whole constructor becomes empty. static llvm::once_flag InitializeRegisterBankFlag; static auto InitializeRegisterBankOnce = [&]() { const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID); (void)RBGPR; assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up"); // Initialize the GPR bank. assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers( *TRI.getRegClass(ARM::tGPREven_and_tGPR_and_tcGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) && "Subclass not added?"); assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit"); #ifndef NDEBUG ARM::checkPartialMappings(); ARM::checkValueMappings(); #endif }; llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce); } const RegisterBank & ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const { using namespace ARM; switch (RC.getID()) { case GPRRegClassID: case GPRwithAPSRRegClassID: case GPRnopcRegClassID: case rGPRRegClassID: case GPRspRegClassID: case tGPR_and_tcGPRRegClassID: case tcGPRRegClassID: case tGPRRegClassID: case tGPREvenRegClassID: case tGPROddRegClassID: case tGPR_and_tGPREvenRegClassID: case tGPR_and_tGPROddRegClassID: case tGPREven_and_tcGPRRegClassID: case tGPREven_and_tGPR_and_tcGPRRegClassID: case tGPROdd_and_tcGPRRegClassID: return getRegBank(ARM::GPRRegBankID); case HPRRegClassID: case SPR_8RegClassID: case SPRRegClassID: case DPR_8RegClassID: case DPRRegClassID: case QPRRegClassID: return getRegBank(ARM::FPRRegBankID); default: llvm_unreachable("Unsupported register kind"); } llvm_unreachable("Switch should handle all register classes"); } const RegisterBankInfo::InstructionMapping & ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { auto Opc = MI.getOpcode(); // Try the default logic for non-generic instructions that are either copies // or already have some operands assigned to banks. if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) { const InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; } using namespace TargetOpcode; const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); unsigned NumOperands = MI.getNumOperands(); const ValueMapping *OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx]; switch (Opc) { case G_ADD: case G_SUB: { // Integer operations where the source and destination are in the // same register class. LLT Ty = MRI.getType(MI.getOperand(0).getReg()); OperandsMapping = Ty.getSizeInBits() == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx] : &ARM::ValueMappings[ARM::GPR3OpsIdx]; break; } case G_MUL: case G_AND: case G_OR: case G_XOR: case G_LSHR: case G_ASHR: case G_SHL: case G_SDIV: case G_UDIV: case G_SEXT: case G_ZEXT: case G_ANYEXT: case G_PTR_ADD: case G_INTTOPTR: case G_PTRTOINT: case G_CTLZ: // FIXME: We're abusing the fact that everything lives in a GPR for now; in // the real world we would use different mappings. OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx]; break; case G_TRUNC: { // In some cases we may end up with a G_TRUNC from a 64-bit value to a // 32-bit value. This isn't a real floating point trunc (that would be a // G_FPTRUNC). Instead it is an integer trunc in disguise, which can appear // because the legalizer doesn't distinguish between integer and floating // point values so it may leave some 64-bit integers un-narrowed. Until we // have a more principled solution that doesn't let such things sneak all // the way to this point, just map the source to a DPR and the destination // to a GPR. LLT LargeTy = MRI.getType(MI.getOperand(1).getReg()); OperandsMapping = LargeTy.getSizeInBits() <= 32 ? &ARM::ValueMappings[ARM::GPR3OpsIdx] : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx]}); break; } case G_LOAD: case G_STORE: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); OperandsMapping = Ty.getSizeInBits() == 64 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}) : &ARM::ValueMappings[ARM::GPR3OpsIdx]; break; } case G_FADD: case G_FSUB: case G_FMUL: case G_FDIV: case G_FNEG: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); OperandsMapping =Ty.getSizeInBits() == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx] : &ARM::ValueMappings[ARM::SPR3OpsIdx]; break; } case G_FMA: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); OperandsMapping = Ty.getSizeInBits() == 64 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx]}) : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], &ARM::ValueMappings[ARM::SPR3OpsIdx], &ARM::ValueMappings[ARM::SPR3OpsIdx], &ARM::ValueMappings[ARM::SPR3OpsIdx]}); break; } case G_FPEXT: { LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); if (ToTy.getSizeInBits() == 64 && FromTy.getSizeInBits() == 32) OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::SPR3OpsIdx]}); break; } case G_FPTRUNC: { LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); if (ToTy.getSizeInBits() == 32 && FromTy.getSizeInBits() == 64) OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx]}); break; } case G_FPTOSI: case G_FPTOUI: { LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); if ((FromTy.getSizeInBits() == 32 || FromTy.getSizeInBits() == 64) && ToTy.getSizeInBits() == 32) OperandsMapping = FromTy.getSizeInBits() == 64 ? getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx]}) : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::SPR3OpsIdx]}); break; } case G_SITOFP: case G_UITOFP: { LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); if (FromTy.getSizeInBits() == 32 && (ToTy.getSizeInBits() == 32 || ToTy.getSizeInBits() == 64)) OperandsMapping = ToTy.getSizeInBits() == 64 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}) : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}); break; } case G_FCONSTANT: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); OperandsMapping = getOperandsMapping( {Ty.getSizeInBits() == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx] : &ARM::ValueMappings[ARM::SPR3OpsIdx], nullptr}); break; } case G_CONSTANT: case G_FRAME_INDEX: case G_GLOBAL_VALUE: OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr}); break; case G_SELECT: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); (void)Ty; LLT Ty2 = MRI.getType(MI.getOperand(1).getReg()); (void)Ty2; assert(Ty.getSizeInBits() == 32 && "Unsupported size for G_SELECT"); assert(Ty2.getSizeInBits() == 1 && "Unsupported size for G_SELECT"); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}); break; } case G_ICMP: { LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); (void)Ty2; assert(Ty2.getSizeInBits() == 32 && "Unsupported size for G_ICMP"); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr, &ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}); break; } case G_FCMP: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); (void)Ty; LLT Ty1 = MRI.getType(MI.getOperand(2).getReg()); LLT Ty2 = MRI.getType(MI.getOperand(3).getReg()); (void)Ty2; assert(Ty.getSizeInBits() == 1 && "Unsupported size for G_FCMP"); assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() && "Mismatched operand sizes for G_FCMP"); unsigned Size = Ty1.getSizeInBits(); assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP"); auto FPRValueMapping = Size == 32 ? &ARM::ValueMappings[ARM::SPR3OpsIdx] : &ARM::ValueMappings[ARM::DPR3OpsIdx]; OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr, FPRValueMapping, FPRValueMapping}); break; } case G_MERGE_VALUES: { // We only support G_MERGE_VALUES for creating a double precision floating // point value out of two GPRs. LLT Ty = MRI.getType(MI.getOperand(0).getReg()); LLT Ty1 = MRI.getType(MI.getOperand(1).getReg()); LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 || Ty2.getSizeInBits() != 32) return getInvalidInstructionMapping(); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx]}); break; } case G_UNMERGE_VALUES: { // We only support G_UNMERGE_VALUES for splitting a double precision // floating point value into two GPRs. LLT Ty = MRI.getType(MI.getOperand(0).getReg()); LLT Ty1 = MRI.getType(MI.getOperand(1).getReg()); LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 32 || Ty2.getSizeInBits() != 64) return getInvalidInstructionMapping(); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx]}); break; } case G_BR: OperandsMapping = getOperandsMapping({nullptr}); break; case G_BRCOND: OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr}); break; case DBG_VALUE: { SmallVector<const ValueMapping *, 4> OperandBanks(NumOperands); const MachineOperand &MaybeReg = MI.getOperand(0); if (MaybeReg.isReg() && MaybeReg.getReg()) { unsigned Size = MRI.getType(MaybeReg.getReg()).getSizeInBits(); if (Size > 32 && Size != 64) return getInvalidInstructionMapping(); OperandBanks[0] = Size == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx] : &ARM::ValueMappings[ARM::GPR3OpsIdx]; } OperandsMapping = getOperandsMapping(OperandBanks); break; } default: return getInvalidInstructionMapping(); } #ifndef NDEBUG for (unsigned i = 0; i < NumOperands; i++) { for (const auto &Mapping : OperandsMapping[i]) { assert( (Mapping.RegBank->getID() != ARM::FPRRegBankID || MF.getSubtarget<ARMSubtarget>().hasVFP2Base()) && "Trying to use floating point register bank on target without vfp"); } } #endif return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, NumOperands); }
Upload File
Create Folder