From 13a9cf28a1202aa401aec5e0b90268e52d74c360 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 5 Dec 2018 20:18:09 +0000 Subject: [PATCH] [Hexagon] Foundation of support for Hexagon V66 llvm-svn: 348407 --- llvm/include/llvm/BinaryFormat/ELF.h | 2 + .../Hexagon/Disassembler/HexagonDisassembler.cpp | 16 +++++ llvm/lib/Target/Hexagon/Hexagon.td | 19 ++++- llvm/lib/Target/Hexagon/HexagonBitTracker.cpp | 15 ++-- llvm/lib/Target/Hexagon/HexagonDepArch.h | 2 +- llvm/lib/Target/Hexagon/HexagonDepArch.td | 10 +-- llvm/lib/Target/Hexagon/HexagonDepITypes.h | 84 +++++++++++----------- llvm/lib/Target/Hexagon/HexagonDepITypes.td | 84 +++++++++++----------- llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp | 3 + llvm/lib/Target/Hexagon/HexagonRegisterInfo.td | 64 ++++++++++------- llvm/lib/Target/Hexagon/HexagonSubtarget.cpp | 1 + llvm/lib/Target/Hexagon/HexagonSubtarget.h | 8 +++ .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 26 +++++-- .../Hexagon/MCTargetDesc/HexagonShuffler.cpp | 16 ++++- .../Target/Hexagon/MCTargetDesc/HexagonShuffler.h | 3 +- 15 files changed, 228 insertions(+), 125 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 3a999bc..b3cd315 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -582,6 +582,7 @@ enum { EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60 EF_HEXAGON_MACH_V62 = 0x00000062, // Hexagon V62 EF_HEXAGON_MACH_V65 = 0x00000065, // Hexagon V65 + EF_HEXAGON_MACH_V66 = 0x00000066, // Hexagon V66 // Highest ISA version flags EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[11:0] @@ -594,6 +595,7 @@ enum { EF_HEXAGON_ISA_V60 = 0x00000060, // Hexagon V60 ISA EF_HEXAGON_ISA_V62 = 0x00000062, // Hexagon V62 ISA EF_HEXAGON_ISA_V65 = 0x00000065, // Hexagon V65 ISA + EF_HEXAGON_ISA_V66 = 0x00000066, // Hexagon V66 ISA }; // Hexagon-specific section indexes for common small data diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 9051c0f..428b42e 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -117,6 +117,10 @@ DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); @@ -608,6 +612,18 @@ static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, return (DecodeRegisterClass(Inst, RegNo >> 1, HvxWRDecoderTable)); } +LLVM_ATTRIBUTE_UNUSED // Suppress warning temporarily. +static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t /*Address*/, + const void *Decoder) { + static const MCPhysReg HvxVQRDecoderTable[] = { + Hexagon::VQ0, Hexagon::VQ1, Hexagon::VQ2, Hexagon::VQ3, + Hexagon::VQ4, Hexagon::VQ5, Hexagon::VQ6, Hexagon::VQ7}; + + return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable); +} + static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, const void *Decoder) { diff --git a/llvm/lib/Target/Hexagon/Hexagon.td b/llvm/lib/Target/Hexagon/Hexagon.td index 10baca5..414edc1 100644 --- a/llvm/lib/Target/Hexagon/Hexagon.td +++ b/llvm/lib/Target/Hexagon/Hexagon.td @@ -25,6 +25,9 @@ include "llvm/Target/Target.td" include "HexagonDepArch.td" // Hexagon ISA Extensions +def ExtensionZReg: SubtargetFeature<"zreg", "UseZRegOps", "true", + "Hexagon ZReg extension instructions">; + def ExtensionHVX: SubtargetFeature<"hvx", "HexagonHVXVersion", "Hexagon::ArchEnum::V60", "Hexagon HVX instructions">; def ExtensionHVXV60: SubtargetFeature<"hvxv60", "HexagonHVXVersion", @@ -32,10 +35,14 @@ def ExtensionHVXV60: SubtargetFeature<"hvxv60", "HexagonHVXVersion", [ExtensionHVX]>; def ExtensionHVXV62: SubtargetFeature<"hvxv62", "HexagonHVXVersion", "Hexagon::ArchEnum::V62", "Hexagon HVX instructions", - [ExtensionHVX,ExtensionHVXV60]>; + [ExtensionHVX, ExtensionHVXV60]>; def ExtensionHVXV65: SubtargetFeature<"hvxv65", "HexagonHVXVersion", "Hexagon::ArchEnum::V65", "Hexagon HVX instructions", - [ExtensionHVX,ExtensionHVXV60, ExtensionHVXV62]>; + [ExtensionHVX, ExtensionHVXV60, ExtensionHVXV62]>; +def ExtensionHVXV66: SubtargetFeature<"hvxv66", "HexagonHVXVersion", + "Hexagon::ArchEnum::V66", "Hexagon HVX instructions", + [ExtensionHVX, ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65, + ExtensionZReg]>; def ExtensionHVX64B: SubtargetFeature<"hvx-length64b", "UseHVX64BOps", "true", "Hexagon HVX 64B instructions", [ExtensionHVX]>; @@ -81,6 +88,10 @@ def UseHVXV62 : Predicate<"HST->useHVXOps()">, AssemblerPredicate<"ExtensionHVXV62">; def UseHVXV65 : Predicate<"HST->useHVXOps()">, AssemblerPredicate<"ExtensionHVXV65">; +def UseHVXV66 : Predicate<"HST->useHVXOps()">, + AssemblerPredicate<"ExtensionHVXV66">; +def UseZReg : Predicate<"HST->useZRegOps()">, + AssemblerPredicate<"ExtensionZReg">; def Hvx64: HwMode<"+hvx-length64b">; def Hvx128: HwMode<"+hvx-length128b">; @@ -347,6 +358,10 @@ def : Proc<"hexagonv65", HexagonModelV65, [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, FeatureDuplex, FeatureMemNoShuf, FeatureMemops, FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>; +def : Proc<"hexagonv66", HexagonModelV65, // Use v65, to be fixed soon. + [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, ArchV66, + FeatureDuplex, FeatureMemNoShuf, FeatureMemops, FeatureNVJ, + FeatureNVS, FeaturePackets, FeatureSmallData]>; //===----------------------------------------------------------------------===// // Declare the target which we are implementing diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp index 94aacbe..92b6da8 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp @@ -93,11 +93,12 @@ BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const { const TargetRegisterClass &RC = *MRI.getRegClass(Reg); unsigned ID = RC.getID(); uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub)); - auto &HRI = static_cast(TRI); + const auto &HRI = static_cast(TRI); bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo)); switch (ID) { case Hexagon::DoubleRegsRegClassID: case Hexagon::HvxWRRegClassID: + case Hexagon::HvxVQRRegClassID: return IsSubLo ? BT::BitMask(0, RW-1) : BT::BitMask(RW, 2*RW-1); default: @@ -114,9 +115,13 @@ uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const { assert(TargetRegisterInfo::isPhysicalRegister(Reg)); using namespace Hexagon; - for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass}) - if (RC.contains(Reg)) - return TRI.getRegSizeInBits(RC); + const auto &HST = MF.getSubtarget(); + if (HST.useHVXOps()) { + for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass, + HvxVQRRegClass}) + if (RC.contains(Reg)) + return TRI.getRegSizeInBits(RC); + } // Default treatment for other physical registers. if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg)) return TRI.getRegSizeInBits(*RC); @@ -142,6 +147,8 @@ const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex( return Hexagon::IntRegsRegClass; case Hexagon::HvxWRRegClassID: return Hexagon::HvxVRRegClass; + case Hexagon::HvxVQRRegClassID: + return Hexagon::HvxWRRegClass; default: break; } diff --git a/llvm/lib/Target/Hexagon/HexagonDepArch.h b/llvm/lib/Target/Hexagon/HexagonDepArch.h index 29199e6..dff2b2f 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepArch.h +++ b/llvm/lib/Target/Hexagon/HexagonDepArch.h @@ -14,7 +14,7 @@ #define HEXAGON_DEP_ARCH_H namespace llvm { namespace Hexagon { -enum class ArchEnum { NoArch, Generic, V5, V55, V60, V62, V65 }; +enum class ArchEnum { NoArch, Generic, V5, V55, V60, V62, V65, V66 }; } // namespace Hexagon } // namespace llvm; #endif // HEXAGON_DEP_ARCH_H diff --git a/llvm/lib/Target/Hexagon/HexagonDepArch.td b/llvm/lib/Target/Hexagon/HexagonDepArch.td index 243354b..f1aadae 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepArch.td +++ b/llvm/lib/Target/Hexagon/HexagonDepArch.td @@ -9,13 +9,15 @@ // Automatically generated file, please consult code owner before editing. //===----------------------------------------------------------------------===// -def ArchV60: SubtargetFeature<"v60", "HexagonArchVersion", "Hexagon::ArchEnum::V60", "Enable Hexagon V60 architecture">; -def HasV60 : Predicate<"HST->hasV60Ops()">, AssemblerPredicate<"ArchV60">; +def ArchV66: SubtargetFeature<"v66", "HexagonArchVersion", "Hexagon::ArchEnum::V66", "Enable Hexagon V66 architecture">; +def HasV66 : Predicate<"HST->hasV66Ops()">, AssemblerPredicate<"ArchV66">; def ArchV65: SubtargetFeature<"v65", "HexagonArchVersion", "Hexagon::ArchEnum::V65", "Enable Hexagon V65 architecture">; def HasV65 : Predicate<"HST->hasV65Ops()">, AssemblerPredicate<"ArchV65">; -def ArchV55: SubtargetFeature<"v55", "HexagonArchVersion", "Hexagon::ArchEnum::V55", "Enable Hexagon V55 architecture">; -def HasV55 : Predicate<"HST->hasV55Ops()">, AssemblerPredicate<"ArchV55">; def ArchV62: SubtargetFeature<"v62", "HexagonArchVersion", "Hexagon::ArchEnum::V62", "Enable Hexagon V62 architecture">; def HasV62 : Predicate<"HST->hasV62Ops()">, AssemblerPredicate<"ArchV62">; +def ArchV60: SubtargetFeature<"v60", "HexagonArchVersion", "Hexagon::ArchEnum::V60", "Enable Hexagon V60 architecture">; +def HasV60 : Predicate<"HST->hasV60Ops()">, AssemblerPredicate<"ArchV60">; +def ArchV55: SubtargetFeature<"v55", "HexagonArchVersion", "Hexagon::ArchEnum::V55", "Enable Hexagon V55 architecture">; +def HasV55 : Predicate<"HST->hasV55Ops()">, AssemblerPredicate<"ArchV55">; def ArchV5: SubtargetFeature<"v5", "HexagonArchVersion", "Hexagon::ArchEnum::V5", "Enable Hexagon V5 architecture">; def HasV5 : Predicate<"HST->hasV5Ops()">, AssemblerPredicate<"ArchV5">; diff --git a/llvm/lib/Target/Hexagon/HexagonDepITypes.h b/llvm/lib/Target/Hexagon/HexagonDepITypes.h index cd9fbc8..81e3971 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepITypes.h +++ b/llvm/lib/Target/Hexagon/HexagonDepITypes.h @@ -17,47 +17,49 @@ enum Type { TypeALU32_ADDI = 2, TypeALU64 = 3, TypeCJ = 4, - TypeCR = 5, - TypeCVI_4SLOT_MPY = 6, - TypeCVI_GATHER = 7, - TypeCVI_GATHER_RST = 8, - TypeCVI_HIST = 9, - TypeCVI_SCATTER = 10, - TypeCVI_SCATTER_DV = 11, - TypeCVI_SCATTER_NEW_RST = 12, - TypeCVI_SCATTER_NEW_ST = 13, - TypeCVI_SCATTER_RST = 14, - TypeCVI_VA = 15, - TypeCVI_VA_DV = 16, - TypeCVI_VINLANESAT = 17, - TypeCVI_VM_LD = 18, - TypeCVI_VM_NEW_ST = 19, - TypeCVI_VM_ST = 20, - TypeCVI_VM_STU = 21, - TypeCVI_VM_TMP_LD = 22, - TypeCVI_VM_VP_LDU = 23, - TypeCVI_VP = 24, - TypeCVI_VP_VS = 25, - TypeCVI_VS = 26, - TypeCVI_VS_VX = 27, - TypeCVI_VX = 28, - TypeCVI_VX_DV = 29, - TypeCVI_VX_LATE = 30, - TypeDUPLEX = 32, - TypeENDLOOP = 33, - TypeEXTENDER = 34, - TypeJ = 35, - TypeLD = 36, - TypeM = 37, - TypeMAPPING = 38, - TypeNCJ = 39, - TypePSEUDO = 40, - TypeST = 41, - TypeSUBINSN = 42, - TypeS_2op = 43, - TypeS_3op = 44, - TypeV2LDST = 47, - TypeV4LDST = 48, + TypeCOPROC_VX = 5, + TypeCR = 6, + TypeCVI_4SLOT_MPY = 7, + TypeCVI_GATHER = 8, + TypeCVI_GATHER_RST = 9, + TypeCVI_HIST = 10, + TypeCVI_SCATTER = 11, + TypeCVI_SCATTER_DV = 12, + TypeCVI_SCATTER_NEW_RST = 13, + TypeCVI_SCATTER_NEW_ST = 14, + TypeCVI_SCATTER_RST = 15, + TypeCVI_VA = 16, + TypeCVI_VA_DV = 17, + TypeCVI_VINLANESAT = 18, + TypeCVI_VM_LD = 19, + TypeCVI_VM_NEW_ST = 20, + TypeCVI_VM_ST = 21, + TypeCVI_VM_STU = 22, + TypeCVI_VM_TMP_LD = 23, + TypeCVI_VM_VP_LDU = 24, + TypeCVI_VP = 25, + TypeCVI_VP_VS = 26, + TypeCVI_VS = 27, + TypeCVI_VS_VX = 28, + TypeCVI_VX = 29, + TypeCVI_VX_DV = 30, + TypeCVI_VX_LATE = 31, + TypeCVI_ZW = 32, + TypeDUPLEX = 33, + TypeENDLOOP = 34, + TypeEXTENDER = 35, + TypeJ = 36, + TypeLD = 37, + TypeM = 38, + TypeMAPPING = 39, + TypeNCJ = 40, + TypePSEUDO = 41, + TypeST = 42, + TypeSUBINSN = 43, + TypeS_2op = 44, + TypeS_3op = 45, + TypeV2LDST = 48, + TypeV4LDST = 49, }; } } diff --git a/llvm/lib/Target/Hexagon/HexagonDepITypes.td b/llvm/lib/Target/Hexagon/HexagonDepITypes.td index 6e6b841..f694062 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepITypes.td +++ b/llvm/lib/Target/Hexagon/HexagonDepITypes.td @@ -15,44 +15,46 @@ def TypeALU32_3op : IType<1>; def TypeALU32_ADDI : IType<2>; def TypeALU64 : IType<3>; def TypeCJ : IType<4>; -def TypeCR : IType<5>; -def TypeCVI_4SLOT_MPY : IType<6>; -def TypeCVI_GATHER : IType<7>; -def TypeCVI_GATHER_RST : IType<8>; -def TypeCVI_HIST : IType<9>; -def TypeCVI_SCATTER : IType<10>; -def TypeCVI_SCATTER_DV : IType<11>; -def TypeCVI_SCATTER_NEW_RST : IType<12>; -def TypeCVI_SCATTER_NEW_ST : IType<13>; -def TypeCVI_SCATTER_RST : IType<14>; -def TypeCVI_VA : IType<15>; -def TypeCVI_VA_DV : IType<16>; -def TypeCVI_VINLANESAT : IType<17>; -def TypeCVI_VM_LD : IType<18>; -def TypeCVI_VM_NEW_ST : IType<19>; -def TypeCVI_VM_ST : IType<20>; -def TypeCVI_VM_STU : IType<21>; -def TypeCVI_VM_TMP_LD : IType<22>; -def TypeCVI_VM_VP_LDU : IType<23>; -def TypeCVI_VP : IType<24>; -def TypeCVI_VP_VS : IType<25>; -def TypeCVI_VS : IType<26>; -def TypeCVI_VS_VX : IType<27>; -def TypeCVI_VX : IType<28>; -def TypeCVI_VX_DV : IType<29>; -def TypeCVI_VX_LATE : IType<30>; -def TypeDUPLEX : IType<32>; -def TypeENDLOOP : IType<33>; -def TypeEXTENDER : IType<34>; -def TypeJ : IType<35>; -def TypeLD : IType<36>; -def TypeM : IType<37>; -def TypeMAPPING : IType<38>; -def TypeNCJ : IType<39>; -def TypePSEUDO : IType<40>; -def TypeST : IType<41>; -def TypeSUBINSN : IType<42>; -def TypeS_2op : IType<43>; -def TypeS_3op : IType<44>; -def TypeV2LDST : IType<47>; -def TypeV4LDST : IType<48>; +def TypeCOPROC_VX : IType<5>; +def TypeCR : IType<6>; +def TypeCVI_4SLOT_MPY : IType<7>; +def TypeCVI_GATHER : IType<8>; +def TypeCVI_GATHER_RST : IType<9>; +def TypeCVI_HIST : IType<10>; +def TypeCVI_SCATTER : IType<11>; +def TypeCVI_SCATTER_DV : IType<12>; +def TypeCVI_SCATTER_NEW_RST : IType<13>; +def TypeCVI_SCATTER_NEW_ST : IType<14>; +def TypeCVI_SCATTER_RST : IType<15>; +def TypeCVI_VA : IType<16>; +def TypeCVI_VA_DV : IType<17>; +def TypeCVI_VINLANESAT : IType<18>; +def TypeCVI_VM_LD : IType<19>; +def TypeCVI_VM_NEW_ST : IType<20>; +def TypeCVI_VM_ST : IType<21>; +def TypeCVI_VM_STU : IType<22>; +def TypeCVI_VM_TMP_LD : IType<23>; +def TypeCVI_VM_VP_LDU : IType<24>; +def TypeCVI_VP : IType<25>; +def TypeCVI_VP_VS : IType<26>; +def TypeCVI_VS : IType<27>; +def TypeCVI_VS_VX : IType<28>; +def TypeCVI_VX : IType<29>; +def TypeCVI_VX_DV : IType<30>; +def TypeCVI_VX_LATE : IType<31>; +def TypeCVI_ZW : IType<32>; +def TypeDUPLEX : IType<33>; +def TypeENDLOOP : IType<34>; +def TypeEXTENDER : IType<35>; +def TypeJ : IType<36>; +def TypeLD : IType<37>; +def TypeM : IType<38>; +def TypeMAPPING : IType<39>; +def TypeNCJ : IType<40>; +def TypePSEUDO : IType<41>; +def TypeST : IType<42>; +def TypeSUBINSN : IType<43>; +def TypeS_2op : IType<44>; +def TypeS_3op : IType<45>; +def TypeV2LDST : IType<48>; +def TypeV4LDST : IType<49>; diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index 545def4..9b8f4e0 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -312,6 +312,7 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex( static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi }; static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi }; + static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi }; switch (RC.getID()) { case Hexagon::CtrRegs64RegClassID: @@ -319,6 +320,8 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex( return ISub[GenIdx]; case Hexagon::HvxWRRegClassID: return VSub[GenIdx]; + case Hexagon::HvxVQRRegClassID: + return WSub[GenIdx]; } if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses()) diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index 1fe1ef4..da90911 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -82,13 +82,14 @@ let Namespace = "Hexagon" in { def isub_hi : SubRegIndex<32, 32>; def vsub_lo : SubRegIndex<512>; def vsub_hi : SubRegIndex<512, 512>; + def wsub_lo : SubRegIndex<1024>; + def wsub_hi : SubRegIndex<1024, 1024>; def subreg_overflow : SubRegIndex<1, 0>; // Integer registers. foreach i = 0-28 in { def R#i : Ri, DwarfRegNum<[i]>; } - def R29 : Ri<29, "r29", ["sp"]>, DwarfRegNum<[29]>; def R30 : Ri<30, "r30", ["fp"]>, DwarfRegNum<[30]>; def R31 : Ri<31, "r31", ["lr"]>, DwarfRegNum<[31]>; @@ -206,6 +207,18 @@ let Namespace = "Hexagon" in { def W15 : Rd<30, "v31:30", [V30, V31]>, DwarfRegNum<[129]>; } + // Aliases of the V* registers used to hold quad vec values. + let SubRegIndices = [wsub_lo, wsub_hi], CoveredBySubRegs = 1 in { + def VQ0 : Rd< 0, "v3:0", [W0, W1]>, DwarfRegNum<[252]>; + def VQ1 : Rd< 4, "v7:4", [W2, W3]>, DwarfRegNum<[253]>; + def VQ2 : Rd< 8, "v11:8", [W4, W5]>, DwarfRegNum<[254]>; + def VQ3 : Rd<12, "v15:12", [W6, W7]>, DwarfRegNum<[255]>; + def VQ4 : Rd<16, "v19:16", [W8, W9]>, DwarfRegNum<[256]>; + def VQ5 : Rd<20, "v23:20", [W10, W11]>, DwarfRegNum<[257]>; + def VQ6 : Rd<24, "v27:24", [W12, W13]>, DwarfRegNum<[258]>; + def VQ7 : Rd<28, "v31:28", [W14, W15]>, DwarfRegNum<[259]>; + } + // Vector Predicate registers. def Q0 : Rq<0, "q0">, DwarfRegNum<[131]>; def Q1 : Rq<1, "q1">, DwarfRegNum<[132]>; @@ -295,29 +308,6 @@ def VecQ32: ValueTypeByHwMode<[Hvx64, Hvx128, DefaultMode], // HVX register classes -// Register classes. -// -// FIXME: the register order should be defined in terms of the preferred -// allocation order... -// -def IntRegs : RegisterClass<"Hexagon", [i32, f32, v4i8, v2i16], 32, - (add (sequence "R%u", 0, 9), (sequence "R%u", 12, 28), - R10, R11, R29, R30, R31)>; - -// Registers are listed in reverse order for allocation preference reasons. -def GeneralSubRegs : RegisterClass<"Hexagon", [i32], 32, - (add R23, R22, R21, R20, R19, R18, R17, R16, - R7, R6, R5, R4, R3, R2, R1, R0)>; - -def IntRegsLow8 : RegisterClass<"Hexagon", [i32], 32, - (add R7, R6, R5, R4, R3, R2, R1, R0)> ; - -def DoubleRegs : RegisterClass<"Hexagon", [i64, f64, v8i8, v4i16, v2i32], 64, - (add (sequence "D%u", 0, 4), (sequence "D%u", 6, 13), D5, D14, D15)>; - -def GeneralDoubleLow8Regs : RegisterClass<"Hexagon", [i64], 64, - (add D11, D10, D9, D8, D3, D2, D1, D0)>; - def HvxVR : RegisterClass<"Hexagon", [VecI8, VecI16, VecI32], 512, (add (sequence "V%u", 0, 31), VTMP)> { let RegInfos = RegInfoByHwMode<[Hvx64, Hvx128, DefaultMode], @@ -336,6 +326,32 @@ def HvxQR : RegisterClass<"Hexagon", [VecI1, VecQ8, VecQ16, VecQ32], 512, [RegInfo<512,512,512>, RegInfo<1024,1024,1024>, RegInfo<512,512,512>]>; } +def HvxVQR : RegisterClass<"Hexagon", [untyped], 2048, + (add (sequence "VQ%u", 0, 7))> { + let RegInfos = RegInfoByHwMode<[Hvx64, Hvx128, DefaultMode], + [RegInfo<2048,2048,2048>, RegInfo<4096,4096,4096>, RegInfo<2048,2048,2048>]>; +} + +// Core register classes + +def IntRegs : RegisterClass<"Hexagon", [i32, f32, v4i8, v2i16], 32, + (add (sequence "R%u", 0, 9), (sequence "R%u", 12, 28), + R10, R11, R29, R30, R31)>; + +// Registers are listed in reverse order for allocation preference reasons. +def GeneralSubRegs : RegisterClass<"Hexagon", [i32], 32, + (add R23, R22, R21, R20, R19, R18, R17, R16, + R7, R6, R5, R4, R3, R2, R1, R0)>; + +def IntRegsLow8 : RegisterClass<"Hexagon", [i32], 32, + (add R7, R6, R5, R4, R3, R2, R1, R0)> ; + +def DoubleRegs : RegisterClass<"Hexagon", [i64, f64, v8i8, v4i16, v2i32], 64, + (add (sequence "D%u", 0, 4), (sequence "D%u", 6, 13), D5, D14, D15)>; + +def GeneralDoubleLow8Regs : RegisterClass<"Hexagon", [i64], 64, + (add D11, D10, D9, D8, D3, D2, D1, D0)>; + let Size = 32 in def PredRegs : RegisterClass<"Hexagon", [i1, v2i1, v4i1, v8i1, v4i8, v2i16, i32], 32, (add P0, P1, P2, P3)>; diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index 88f63de..9c77135 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -98,6 +98,7 @@ HexagonSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { {"hexagonv60", Hexagon::ArchEnum::V60}, {"hexagonv62", Hexagon::ArchEnum::V62}, {"hexagonv65", Hexagon::ArchEnum::V65}, + {"hexagonv66", Hexagon::ArchEnum::V66}, }; auto FoundIt = CpuTable.find(CPUString); diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index de8ac91..3a5acb5 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -52,6 +52,7 @@ class HexagonSubtarget : public HexagonGenSubtargetInfo { bool UseNewValueJumps = false; bool UseNewValueStores = false; bool UseSmallData = false; + bool UseZRegOps = false; bool HasMemNoShuf = false; bool EnableDuplex = false; @@ -151,6 +152,12 @@ public: bool hasV65OpsOnly() const { return getHexagonArchVersion() == Hexagon::ArchEnum::V65; } + bool hasV66Ops() const { + return getHexagonArchVersion() >= Hexagon::ArchEnum::V66; + } + bool hasV66OpsOnly() const { + return getHexagonArchVersion() == Hexagon::ArchEnum::V66; + } bool useLongCalls() const { return UseLongCalls; } bool useMemops() const { return UseMemops; } @@ -158,6 +165,7 @@ public: bool useNewValueJumps() const { return UseNewValueJumps; } bool useNewValueStores() const { return UseNewValueStores; } bool useSmallData() const { return UseSmallData; } + bool useZRegOps() const { return UseZRegOps; } bool useHVXOps() const { return HexagonHVXVersion > Hexagon::ArchEnum::NoArch; diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 8f3c09e..92ce734 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -71,6 +71,8 @@ cl::opt MV62("mv62", cl::Hidden, cl::desc("Build for Hexagon V62"), cl::init(false)); cl::opt MV65("mv65", cl::Hidden, cl::desc("Build for Hexagon V65"), cl::init(false)); +cl::opt MV66("mv66", cl::Hidden, cl::desc("Build for Hexagon V66"), + cl::init(false)); } // namespace cl::opt @@ -80,9 +82,10 @@ cl::opt clEnumValN(Hexagon::ArchEnum::V60, "v60", "Build for HVX v60"), clEnumValN(Hexagon::ArchEnum::V62, "v62", "Build for HVX v62"), clEnumValN(Hexagon::ArchEnum::V65, "v65", "Build for HVX v65"), - // Sentinal for no value specified + clEnumValN(Hexagon::ArchEnum::V66, "v66", "Build for HVX v66"), + // Sentinel for no value specified. clEnumValN(Hexagon::ArchEnum::Generic, "", "")), - // Sentinal for flag not present + // Sentinel for flag not present. cl::init(Hexagon::ArchEnum::NoArch), cl::ValueOptional); static cl::opt @@ -103,6 +106,8 @@ static StringRef HexagonGetArchVariant() { return "hexagonv62"; if (MV65) return "hexagonv65"; + if (MV66) + return "hexagonv66"; return ""; } @@ -289,11 +294,15 @@ std::string selectHexagonFS(StringRef CPU, StringRef FS) { case Hexagon::ArchEnum::V65: Result.push_back("+hvxv65"); break; + case Hexagon::ArchEnum::V66: + Result.push_back("+hvxv66"); + break; case Hexagon::ArchEnum::Generic:{ Result.push_back(StringSwitch(CPU) .Case("hexagonv60", "+hvxv60") .Case("hexagonv62", "+hvxv62") - .Case("hexagonv65", "+hvxv65")); + .Case("hexagonv65", "+hvxv65") + .Case("hexagonv66", "+hvxv66")); break; } case Hexagon::ArchEnum::NoArch: @@ -308,7 +317,7 @@ static bool isCPUValid(std::string CPU) { std::vector table { "generic", "hexagonv5", "hexagonv55", "hexagonv60", - "hexagonv62", "hexagonv65", + "hexagonv62", "hexagonv65", "hexagonv66", }; return std::find(table.begin(), table.end(), CPU) != table.end(); @@ -330,7 +339,7 @@ FeatureBitset Hexagon_MC::completeHVXFeatures(const FeatureBitset &S) { // turns on hvxvNN, corresponding to the existing ArchVNN. FeatureBitset FB = S; unsigned CpuArch = ArchV5; - for (unsigned F : {ArchV65, ArchV62, ArchV60, ArchV55, ArchV5}) { + for (unsigned F : {ArchV66, ArchV65, ArchV62, ArchV60, ArchV55, ArchV5}) { if (!FB.test(F)) continue; CpuArch = F; @@ -344,7 +353,8 @@ FeatureBitset Hexagon_MC::completeHVXFeatures(const FeatureBitset &S) { break; } bool HasHvxVer = false; - for (unsigned F : {ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65}) { + for (unsigned F : {ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65, + ExtensionHVXV66}) { if (!FB.test(F)) continue; HasHvxVer = true; @@ -357,6 +367,9 @@ FeatureBitset Hexagon_MC::completeHVXFeatures(const FeatureBitset &S) { // HasHvxVer is false, and UseHvx is true. switch (CpuArch) { + case ArchV66: + FB.set(ExtensionHVXV66); + LLVM_FALLTHROUGH; case ArchV65: FB.set(ExtensionHVXV65); LLVM_FALLTHROUGH; @@ -400,6 +413,7 @@ unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) { {"hexagonv60", ELF::EF_HEXAGON_MACH_V60}, {"hexagonv62", ELF::EF_HEXAGON_MACH_V62}, {"hexagonv65", ELF::EF_HEXAGON_MACH_V65}, + {"hexagonv66", ELF::EF_HEXAGON_MACH_V66}, }; auto F = ElfFlags.find(STI.getCPU()); diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp index 59f3caa..f4ee2bb 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp @@ -138,6 +138,8 @@ void HexagonCVIResource::SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU) { UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2); (*TUL)[HexagonII::TypeCVI_SCATTER_NEW_ST] = UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1); + (*TUL)[HexagonII::TypeCVI_4SLOT_MPY] = UnitsAndLanes(CVI_XLANE, 4); + (*TUL)[HexagonII::TypeCVI_ZW] = UnitsAndLanes(CVI_ZW, 1); } HexagonCVIResource::HexagonCVIResource(TypeUnitsAndLanes *TUL, @@ -300,6 +302,7 @@ bool HexagonShuffler::check() { // Number of memory operations, loads, solo loads, stores, solo stores, single // stores. unsigned memory = 0, loads = 0, load0 = 0, stores = 0, store0 = 0, store1 = 0; + unsigned NonZCVIloads = 0, AllCVIloads = 0, CVIstores = 0; // Number of duplex insns unsigned duplex = 0; unsigned pSlot3Cnt = 0; @@ -331,6 +334,11 @@ bool HexagonShuffler::check() { case HexagonII::TypeCVI_VM_TMP_LD: case HexagonII::TypeCVI_GATHER: case HexagonII::TypeCVI_GATHER_RST: + ++NonZCVIloads; + LLVM_FALLTHROUGH; + case HexagonII::TypeCVI_ZW: + ++AllCVIloads; + LLVM_FALLTHROUGH; case HexagonII::TypeLD: ++loads; ++memory; @@ -348,6 +356,8 @@ bool HexagonShuffler::check() { case HexagonII::TypeCVI_SCATTER_RST: case HexagonII::TypeCVI_SCATTER_NEW_RST: case HexagonII::TypeCVI_SCATTER_NEW_ST: + ++CVIstores; + LLVM_FALLTHROUGH; case HexagonII::TypeST: ++stores; ++memory; @@ -405,7 +415,11 @@ bool HexagonShuffler::check() { applySlotRestrictions(); // Check if the packet is legal. - if ((load0 > 1 || store0 > 1) || (duplex > 1 || (duplex && memory))) { + const unsigned ZCVIloads = AllCVIloads - NonZCVIloads; + const bool ValidHVXMem = + NonZCVIloads <= 1 && ZCVIloads <= 1 && CVIstores <= 1; + if ((load0 > 1 || store0 > 1 || !ValidHVXMem) || + (duplex > 1 || (duplex && memory))) { reportError(llvm::Twine("invalid instruction packet")); return false; } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h index 37f90bc..ef50c5b 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h @@ -75,7 +75,8 @@ private: CVI_XLANE = 1 << 0, CVI_SHIFT = 1 << 1, CVI_MPY0 = 1 << 2, - CVI_MPY1 = 1 << 3 + CVI_MPY1 = 1 << 3, + CVI_ZW = 1 << 4 }; // Count of adjacent slots that the insn requires to be executed. -- 2.7.4