forked from OSchip/llvm-project
[Hexagon] Foundation of support for Hexagon V66
llvm-svn: 348407
This commit is contained in:
parent
f75d4f329c
commit
13a9cf28a1
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<const HexagonRegisterInfo&>(TRI);
|
||||
const auto &HRI = static_cast<const HexagonRegisterInfo&>(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<HexagonSubtarget>();
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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<i, "r"#i>, 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)>;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -71,6 +71,8 @@ cl::opt<bool> MV62("mv62", cl::Hidden, cl::desc("Build for Hexagon V62"),
|
|||
cl::init(false));
|
||||
cl::opt<bool> MV65("mv65", cl::Hidden, cl::desc("Build for Hexagon V65"),
|
||||
cl::init(false));
|
||||
cl::opt<bool> MV66("mv66", cl::Hidden, cl::desc("Build for Hexagon V66"),
|
||||
cl::init(false));
|
||||
} // namespace
|
||||
|
||||
cl::opt<Hexagon::ArchEnum>
|
||||
|
@ -80,9 +82,10 @@ cl::opt<Hexagon::ArchEnum>
|
|||
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<bool>
|
||||
|
@ -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<StringRef>(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<std::string> 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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue