1,019 changes: 1,019 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonInstrEnc.td

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class SubTarget<bits<6> value> {

def HasAnySubT : SubTarget<0x3f>; // 111111
def HasV5SubT : SubTarget<0x3e>; // 111110
def HasV55SubT : SubTarget<0x3c>; // 111100
def HasV60SubT : SubTarget<0x38>; // 111000

// Addressing modes for load/store instructions
class AddrModeType<bits<3> value> {
Expand All @@ -57,6 +59,8 @@ def ByteAccess : MemAccessSize<1>;// Byte access instruction (memb).
def HalfWordAccess : MemAccessSize<2>;// Half word access instruction (memh).
def WordAccess : MemAccessSize<3>;// Word access instruction (memw).
def DoubleWordAccess : MemAccessSize<4>;// Double word access instruction (memd)
def Vector64Access : MemAccessSize<7>;// Vector access instruction (memv)
def Vector128Access : MemAccessSize<8>;// Vector access instruction (memv)


//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -167,7 +171,17 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
bits<1> isFP = 0;
let TSFlags {48} = isFP; // Floating-point.

bits<1> hasNewValue2 = 0;
let TSFlags{50} = hasNewValue2; // Second New-value producer insn.
bits<3> opNewValue2 = 0;
let TSFlags{53-51} = opNewValue2; // Second New-value produced operand.

bits<1> isAccumulator = 0;
let TSFlags{54} = isAccumulator;

// Fields used for relation models.
bit isNonTemporal = 0;
string isNT = ""; // set to "true" for non-temporal vector stores.
string BaseOpcode = "";
string CextOpcode = "";
string PredSense = "";
Expand All @@ -182,6 +196,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
"");
let PNewValue = !if(isPredicatedNew, "new", "");
let NValueST = !if(isNVStore, "true", "false");
let isNT = !if(isNonTemporal, "true", "false");

// *** Must match MCTargetDesc/HexagonBaseInfo.h ***
}
Expand Down Expand Up @@ -217,6 +232,11 @@ class LD0Inst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin=LD_tc_ld_SLOT0>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeLD>, OpcodeHexagon;

let mayLoad = 1 in
class LD1Inst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin=LD_tc_ld_SLOT0>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeLD>;

// ST Instruction Class in V2/V3 can take SLOT0 only.
// ST Instruction Class in V4 can take SLOT0 & SLOT1.
// Definition of the instruction class CHANGED from V2/V3 to V4.
Expand All @@ -234,6 +254,12 @@ class ST0Inst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin = ST_tc_ld_SLOT0>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeST>, OpcodeHexagon;

// Same as ST0Inst but doesn't derive from OpcodeHexagon.
let mayStore = 1 in
class ST1Inst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin = ST_tc_st_SLOT0>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeST>;

// ST Instruction Class in V2/V3 can take SLOT0 only.
// ST Instruction Class in V4 can take SLOT0 & SLOT1.
// Definition of the instruction class CHANGED from V2/V3 to V4.
Expand Down Expand Up @@ -277,6 +303,11 @@ class MInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeXTYPE>,
OpcodeHexagon;

// Same as above but doesn't derive from OpcodeHexagon
class MInst2<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin = M_tc_3x_SLOT23>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeXTYPE>;

// M Instruction Class in V2/V3.
// XTYPE Instruction Class in V4.
// Definition of the instruction class NOT CHANGED.
Expand All @@ -294,6 +325,10 @@ class SInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeXTYPE>,
OpcodeHexagon;

class SInst2<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin = S_2op_tc_1_SLOT23>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeXTYPE>;

// S Instruction Class in V2/V3.
// XTYPE Instruction Class in V4.
// Definition of the instruction class NOT CHANGED.
Expand Down Expand Up @@ -402,3 +437,13 @@ include "HexagonInstrFormatsV4.td"
//===----------------------------------------------------------------------===//
// V4 Instruction Format Definitions +
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// V60 Instruction Format Definitions +
//===----------------------------------------------------------------------===//

include "HexagonInstrFormatsV60.td"

//===----------------------------------------------------------------------===//
// V60 Instruction Format Definitions +
//===----------------------------------------------------------------------===//
238 changes: 238 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonInstrFormatsV60.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
//==- HexagonInstrFormatsV60.td - Hexagon Instruction Formats -*- tablegen -==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the Hexagon V60 instruction classes in TableGen format.
//
//===----------------------------------------------------------------------===//

//----------------------------------------------------------------------------//
// Hexagon Intruction Flags +
//
// *** Must match BaseInfo.h ***
//----------------------------------------------------------------------------//

def TypeCVI_VA : IType<13>;
def TypeCVI_VA_DV : IType<14>;
def TypeCVI_VX : IType<15>;
def TypeCVI_VX_DV : IType<16>;
def TypeCVI_VP : IType<17>;
def TypeCVI_VP_VS : IType<18>;
def TypeCVI_VS : IType<19>;
def TypeCVI_VINLANESAT : IType<20>;
def TypeCVI_VM_LD : IType<21>;
def TypeCVI_VM_TMP_LD : IType<22>;
def TypeCVI_VM_CUR_LD : IType<23>;
def TypeCVI_VM_VP_LDU : IType<24>;
def TypeCVI_VM_ST : IType<25>;
def TypeCVI_VM_NEW_ST : IType<26>;
def TypeCVI_VM_STU : IType<27>;
def TypeCVI_HIST : IType<28>;
//----------------------------------------------------------------------------//
// Intruction Classes Definitions +
//----------------------------------------------------------------------------//

let validSubTargets = HasV60SubT in
{
class CVI_VA_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VA>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VA_DV_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VA_DV>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VX_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VX_Resource_late<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX>,
Requires<[HasV60T, UseHVX]>;

class CVI_VX_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VX_DV_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX_DV>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VX_DV_Slot2_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX_DV>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VX_DV_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX_DV>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VP_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VP>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VP_VS_Resource_early<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VP_VS>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VP_VS_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VP_VS>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VP_VS_Resource_long_early<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VP_VS>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VS_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VS>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VINLANESAT_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VINLANESAT>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VS_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VS>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_LD_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_LD>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_LD_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_LD>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_TMP_LD_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_TMP_LD>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_TMP_LD_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_TMP_LD>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_CUR_LD_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_CUR_LD>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_VP_LDU_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_VP_LDU>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_VP_LDU_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_VP_LDU>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_ST_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_ST>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_ST_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_ST>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_NEW_ST_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_NEW_ST>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_NEW_ST_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_NEW_ST>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_STU_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_STU>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_VM_STU_Resource_long<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VM_STU>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;

class CVI_HIST_Resource<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_HIST>,
OpcodeHexagon, Requires<[HasV60T, UseHVX]>;
}

let validSubTargets = HasV60SubT in
{
class CVI_VA_Resource1<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VA>,
Requires<[HasV60T, UseHVX]>;

class CVI_VX_DV_Resource1<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_VX_DV>,
Requires<[HasV60T, UseHVX]>;

class CVI_HIST_Resource1<dag outs, dag ins, string asmstr,
list<dag> pattern = [], string cstr = "",
InstrItinClass itin = PSEUDO>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeCVI_HIST>,
Requires<[HasV60T, UseHVX]>;
}


12 changes: 11 additions & 1 deletion llvm/lib/Target/Hexagon/HexagonInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

include "HexagonInstrFormats.td"
include "HexagonOperands.td"

include "HexagonInstrEnc.td"
// Pattern fragment that combines the value type and the register class
// into a single parameter.
// The pat frags in the definitions below need to have a named register,
Expand Down Expand Up @@ -5783,6 +5783,16 @@ include "HexagonInstrInfoV5.td"
// V5 Instructions -
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// V60 Instructions +
//===----------------------------------------------------------------------===//

include "HexagonInstrInfoV60.td"

//===----------------------------------------------------------------------===//
// V60 Instructions -
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// ALU32/64/Vector +
//===----------------------------------------------------------------------===///
Expand Down
2,211 changes: 2,211 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ def s4_0ImmOperand : AsmOperandClass { let Name = "s4_0Imm"; }
def s4_1ImmOperand : AsmOperandClass { let Name = "s4_1Imm"; }
def s4_2ImmOperand : AsmOperandClass { let Name = "s4_2Imm"; }
def s4_3ImmOperand : AsmOperandClass { let Name = "s4_3Imm"; }
def s4_6ImmOperand : AsmOperandClass { let Name = "s4_6Imm"; }
def s3_6ImmOperand : AsmOperandClass { let Name = "s3_6Imm"; }

// Immediate operands.

Expand Down Expand Up @@ -58,6 +60,19 @@ let PrintMethod = "printImmOperand" in {
def m6Imm : Operand<i32>;
}

let OperandType = "OPERAND_IMMEDIATE" in {
def s4_6Imm : Operand<i32> { let ParserMatchClass = s4_6ImmOperand;
let PrintMethod = "prints4_6ImmOperand";
let DecoderMethod = "s4_6ImmDecoder";}
def s4_7Imm : Operand<i32> { let PrintMethod = "prints4_7ImmOperand";
let DecoderMethod = "s4_6ImmDecoder";}
def s3_6Imm : Operand<i32> { let ParserMatchClass = s3_6ImmOperand;
let PrintMethod = "prints3_6ImmOperand";
let DecoderMethod = "s3_6ImmDecoder";}
def s3_7Imm : Operand<i32> { let PrintMethod = "prints3_7ImmOperand";
let DecoderMethod = "s3_6ImmDecoder";}
}

let PrintMethod = "printNOneImmOperand" in
def nOneImm : Operand<i32>;

Expand Down Expand Up @@ -502,6 +517,43 @@ def u9ExtPred : PatLeaf<(i32 imm), [{
}]>;


def s4_7ImmPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (HST->hasV60TOps())
// Return true if the immediate can fit in a 10-bit sign extended field and
// is 128-byte aligned.
return isShiftedInt<4,7>(v);
return false;
}]>;

def s3_7ImmPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (HST->hasV60TOps())
// Return true if the immediate can fit in a 9-bit sign extended field and
// is 128-byte aligned.
return isShiftedInt<3,7>(v);
return false;
}]>;

def s4_6ImmPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (HST->hasV60TOps())
// Return true if the immediate can fit in a 10-bit sign extended field and
// is 64-byte aligned.
return isShiftedInt<4,6>(v);
return false;
}]>;

def s3_6ImmPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (HST->hasV60TOps())
// Return true if the immediate can fit in a 9-bit sign extended field and
// is 64-byte aligned.
return isShiftedInt<3,6>(v);
return false;
}]>;


// This complex pattern exists only to create a machine instruction operand
// of type "frame index". There doesn't seem to be a way to do that directly
// in the patterns.
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF) const {
switch (HST.getHexagonArchVersion()) {
case HexagonSubtarget::V4:
case HexagonSubtarget::V5:
case HexagonSubtarget::V55:
case HexagonSubtarget::V60:
return CallerSavedRegsV4;
}
llvm_unreachable(
Expand All @@ -84,6 +86,8 @@ HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
case HexagonSubtarget::V4:
case HexagonSubtarget::V5:
case HexagonSubtarget::V55:
case HexagonSubtarget::V60:
return CalleeSavedRegsV3;
}
llvm_unreachable("Callee saved registers requested for unknown architecture "
Expand Down
59 changes: 59 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ let Namespace = "Hexagon" in {
let Num = num;
}


// Rq - vector predicate registers
class Rq<bits<3> num, string n> : Register<n, []> {
let HWEncoding{2-0} = num;
}

// Rc - control registers
class Rc<bits<5> num, string n,
list<string> alt = [], list<Register> alias = []> :
Expand Down Expand Up @@ -158,6 +164,36 @@ let Namespace = "Hexagon" in {
def UPC : Rcc<14, "c15:14", [UPCL, UPCH]>, DwarfRegNum<[80]>;
}

foreach i = 0-31 in {
def V#i : Ri<i, "v"#i>, DwarfRegNum<[!add(i, 99)]>;
}

// Aliases of the V* registers used to hold double vec values.
let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
def W0 : Rd< 0, "v1:0", [V0, V1]>, DwarfRegNum<[99]>;
def W1 : Rd< 2, "v3:2", [V2, V3]>, DwarfRegNum<[101]>;
def W2 : Rd< 4, "v5:4", [V4, V5]>, DwarfRegNum<[103]>;
def W3 : Rd< 6, "v7:6", [V6, V7]>, DwarfRegNum<[105]>;
def W4 : Rd< 8, "v9:8", [V8, V9]>, DwarfRegNum<[107]>;
def W5 : Rd<10, "v11:10", [V10, V11]>, DwarfRegNum<[109]>;
def W6 : Rd<12, "v13:12", [V12, V13]>, DwarfRegNum<[111]>;
def W7 : Rd<14, "v15:14", [V14, V15]>, DwarfRegNum<[113]>;
def W8 : Rd<16, "v17:16", [V16, V17]>, DwarfRegNum<[115]>;
def W9 : Rd<18, "v19:18", [V18, V19]>, DwarfRegNum<[117]>;
def W10 : Rd<20, "v21:20", [V20, V21]>, DwarfRegNum<[119]>;
def W11 : Rd<22, "v23:22", [V22, V23]>, DwarfRegNum<[121]>;
def W12 : Rd<24, "v25:24", [V24, V25]>, DwarfRegNum<[123]>;
def W13 : Rd<26, "v27:26", [V26, V27]>, DwarfRegNum<[125]>;
def W14 : Rd<28, "v29:28", [V28, V29]>, DwarfRegNum<[127]>;
def W15 : Rd<30, "v31:30", [V30, V31]>, DwarfRegNum<[129]>;
}

// Vector Predicate registers.
def Q0 : Rq<0, "q0">, DwarfRegNum<[131]>;
def Q1 : Rq<1, "q1">, DwarfRegNum<[132]>;
def Q2 : Rq<2, "q2">, DwarfRegNum<[133]>;
def Q3 : Rq<3, "q3">, DwarfRegNum<[134]>;

// Register classes.
//
// FIXME: the register order should be defined in terms of the preferred
Expand All @@ -169,10 +205,33 @@ def IntRegs : RegisterClass<"Hexagon", [i32, f32, v4i8, v2i16], 32,
R10, R11, R29, R30, R31)> {
}

// Registers are listed in reverse order for allocation preference reasons.
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 VectorRegs : RegisterClass<"Hexagon", [v64i8, v32i16, v16i32, v8i64], 512,
(add (sequence "V%u", 0, 31))>;

def VecDblRegs : RegisterClass<"Hexagon", [v16i64], 1024,
(add (sequence "W%u", 0, 15))>;

def VectorRegs128B : RegisterClass<"Hexagon",
[v16i64], 1024,
(add (sequence "V%u", 0, 31))>;

def VecDblRegs128B : RegisterClass<"Hexagon",
[v16i64], 2048,
(add (sequence "W%u", 0, 15))>;

def VecPredRegs : RegisterClass<"Hexagon", [v16i32], 512,
(add (sequence "Q%u", 0, 3))>;

def VecPredRegs128B : RegisterClass<"Hexagon", [v16i64], 1024,
(add (sequence "Q%u", 0, 3))>;

def PredRegs : RegisterClass<"Hexagon",
[i1, v2i1, v4i1, v8i1, v4i8, v2i16, i32], 32,
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonSchedule.td
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

include "HexagonScheduleV4.td"

// V55 Machine Info +
include "HexagonScheduleV55.td"

//===----------------------------------------------------------------------===//
// V4 Machine Info -
//===----------------------------------------------------------------------===//

3 changes: 3 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonScheduleV4.td
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def PSEUDOM : InstrItinClass;
// ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4.
def DUPLEX : InstrItinClass;
def PREFIX : InstrItinClass;
def COMPOUND_CJ_ARCHDEPSLOT : InstrItinClass;
def COMPOUND : InstrItinClass;

def ALU32_2op_tc_1_SLOT0123 : InstrItinClass;
Expand All @@ -58,6 +59,7 @@ def CR_tc_2early_SLOT3 : InstrItinClass;
def CR_tc_3x_SLOT23 : InstrItinClass;
def CR_tc_3x_SLOT3 : InstrItinClass;
def J_tc_2early_SLOT23 : InstrItinClass;
def J_tc_2early_CJUMP_UCJUMP_ARCHDEPSLOT : InstrItinClass;
def J_tc_2early_SLOT2 : InstrItinClass;
def LD_tc_ld_SLOT01 : InstrItinClass;
def LD_tc_ld_SLOT0 : InstrItinClass;
Expand Down Expand Up @@ -91,6 +93,7 @@ def V4LDST_tc_st_SLOT0 : InstrItinClass;
def V4LDST_tc_st_SLOT01 : InstrItinClass;
def J_tc_2early_SLOT0123 : InstrItinClass;
def EXTENDER_tc_1_SLOT0123 : InstrItinClass;
def S_3op_tc_3stall_SLOT23 : InstrItinClass;


def HexagonItinerariesV4 :
Expand Down
170 changes: 170 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonScheduleV55.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//=-HexagonScheduleV4.td - HexagonV4 Scheduling Definitions --*- tablegen -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// There are four SLOTS (four parallel pipelines) in Hexagon V4 machine.
// This file describes that machine information.

//
// |===========|==================================================|
// | PIPELINE | Instruction Classes |
// |===========|==================================================|
// | SLOT0 | LD ST ALU32 MEMOP NV SYSTEM |
// |-----------|--------------------------------------------------|
// | SLOT1 | LD ST ALU32 |
// |-----------|--------------------------------------------------|
// | SLOT2 | XTYPE ALU32 J JR |
// |-----------|--------------------------------------------------|
// | SLOT3 | XTYPE ALU32 J CR |
// |===========|==================================================|

def CJ_tc_1_SLOT23 : InstrItinClass;
def CJ_tc_2early_SLOT23 : InstrItinClass;
def COPROC_VMEM_vtc_long_SLOT01 : InstrItinClass;
def COPROC_VX_vtc_long_SLOT23 : InstrItinClass;
def COPROC_VX_vtc_SLOT23 : InstrItinClass;
def J_tc_3stall_SLOT2 : InstrItinClass;
def MAPPING_tc_1_SLOT0123 : InstrItinClass;
def M_tc_3stall_SLOT23 : InstrItinClass;
def SUBINSN_tc_1_SLOT01 : InstrItinClass;
def SUBINSN_tc_2early_SLOT0 : InstrItinClass;
def SUBINSN_tc_2early_SLOT01 : InstrItinClass;
def SUBINSN_tc_3stall_SLOT0 : InstrItinClass;
def SUBINSN_tc_ld_SLOT0 : InstrItinClass;
def SUBINSN_tc_ld_SLOT01 : InstrItinClass;
def SUBINSN_tc_st_SLOT01 : InstrItinClass;

def HexagonItinerariesV55 :
ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3, SLOT_ENDLOOP], [], [
// ALU32
InstrItinData<ALU32_2op_tc_1_SLOT0123 ,
[InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU32_2op_tc_2early_SLOT0123,
[InstrStage<2, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU32_3op_tc_1_SLOT0123 ,
[InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU32_3op_tc_2_SLOT0123 ,
[InstrStage<2, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU32_3op_tc_2early_SLOT0123,
[InstrStage<2, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU32_ADDI_tc_1_SLOT0123 ,
[InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,

// ALU64
InstrItinData<ALU64_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<ALU64_tc_2_SLOT23 , [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<ALU64_tc_2early_SLOT23, [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<ALU64_tc_3x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,

// CR -> System
InstrItinData<CR_tc_2_SLOT3 , [InstrStage<2, [SLOT3]>]>,
InstrItinData<CR_tc_2early_SLOT3 , [InstrStage<2, [SLOT3]>]>,
InstrItinData<CR_tc_3x_SLOT3 , [InstrStage<3, [SLOT3]>]>,

// Jump (conditional/unconditional/return etc)
InstrItinData<CR_tc_2early_SLOT23, [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<CR_tc_3x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<CJ_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<CJ_tc_2early_SLOT23, [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<J_tc_2early_SLOT23 , [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<J_tc_2early_CJUMP_UCJUMP_ARCHDEPSLOT , [InstrStage<1, [SLOT2, SLOT3]>]>,

// JR
InstrItinData<J_tc_2early_SLOT2 , [InstrStage<2, [SLOT2]>]>,
InstrItinData<J_tc_3stall_SLOT2 , [InstrStage<3, [SLOT2]>]>,

// Extender
InstrItinData<EXTENDER_tc_1_SLOT0123,
[InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,

// Load
InstrItinData<LD_tc_ld_SLOT01 , [InstrStage<3, [SLOT0, SLOT1]>]>,
InstrItinData<LD_tc_3or4stall_SLOT0, [InstrStage<3, [SLOT0]>]>,
InstrItinData<LD_tc_ld_SLOT0 , [InstrStage<3, [SLOT0]>]>,

// M
InstrItinData<M_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<M_tc_2_SLOT23 , [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<M_tc_3_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<M_tc_3x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<M_tc_3or4x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<M_tc_3stall_SLOT23, [InstrStage<3, [SLOT2, SLOT3]>]>,

// Store
InstrItinData<ST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<ST_tc_3stall_SLOT0, [InstrStage<3, [SLOT0]>]>,
InstrItinData<ST_tc_ld_SLOT0 , [InstrStage<3, [SLOT0]>]>,
InstrItinData<ST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>,

// Subinsn
InstrItinData<SUBINSN_tc_2early_SLOT0, [InstrStage<2, [SLOT0]>]>,
InstrItinData<SUBINSN_tc_3stall_SLOT0, [InstrStage<3, [SLOT0]>]>,
InstrItinData<SUBINSN_tc_ld_SLOT0 , [InstrStage<3, [SLOT0]>]>,
InstrItinData<SUBINSN_tc_1_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<SUBINSN_tc_2early_SLOT01,
[InstrStage<2, [SLOT0, SLOT1]>]>,
InstrItinData<SUBINSN_tc_ld_SLOT01 , [InstrStage<3, [SLOT0, SLOT1]>]>,
InstrItinData<SUBINSN_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>,

// S
InstrItinData<S_2op_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<S_2op_tc_2_SLOT23 , [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<S_2op_tc_2early_SLOT23, [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<S_2op_tc_3or4x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_1_SLOT23 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_2_SLOT23 , [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_2early_SLOT23, [InstrStage<2, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_3_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_3stall_SLOT23, [InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<S_3op_tc_3x_SLOT23 , [InstrStage<3, [SLOT2, SLOT3]>]>,

// New Value Compare Jump
InstrItinData<NCJ_tc_3or4stall_SLOT0, [InstrStage<3, [SLOT0]>]>,

// Mem ops
InstrItinData<V2LDST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<V2LDST_tc_ld_SLOT01 , [InstrStage<2, [SLOT0, SLOT1]>]>,
InstrItinData<V2LDST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<V4LDST_tc_st_SLOT0 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<V4LDST_tc_ld_SLOT01 , [InstrStage<3, [SLOT0, SLOT1]>]>,
InstrItinData<V4LDST_tc_st_SLOT01 , [InstrStage<1, [SLOT0, SLOT1]>]>,

// Endloop
InstrItinData<J_tc_2early_SLOT0123, [InstrStage<2, [SLOT_ENDLOOP]>]>,

// Vector
InstrItinData<COPROC_VMEM_vtc_long_SLOT01,
[InstrStage<3, [SLOT0, SLOT1]>]>,
InstrItinData<COPROC_VX_vtc_long_SLOT23 ,
[InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<COPROC_VX_vtc_SLOT23 ,
[InstrStage<3, [SLOT2, SLOT3]>]>,
InstrItinData<MAPPING_tc_1_SLOT0123 ,
[InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,

// Misc
InstrItinData<COMPOUND_CJ_ARCHDEPSLOT , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<COMPOUND , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<DUPLEX , [InstrStage<1, [SLOT0]>]>,
InstrItinData<PREFIX , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<PSEUDOM, [InstrStage<1, [SLOT2, SLOT3], 0>,
InstrStage<1, [SLOT2, SLOT3]>]>

]>;

def HexagonModelV55 : SchedMachineModel {
// Max issue per cycle == bundle width.
let IssueWidth = 4;
let Itineraries = HexagonItinerariesV55;
let LoadLatency = 1;
}

//===----------------------------------------------------------------------===//
// Hexagon V4 Resource Definitions -
//===----------------------------------------------------------------------===//
301 changes: 301 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonScheduleV60.td

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions llvm/lib/Target/Hexagon/HexagonSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ namespace llvm {
class HexagonSubtarget : public HexagonGenSubtargetInfo {
virtual void anchor();

bool UseMemOps;
bool UseMemOps, UseHVXOps, UseHVXDblOps;
bool ModeIEEERndNear;

public:
enum HexagonArchEnum {
V4, V5
V4, V5, V55, V60
};

HexagonArchEnum HexagonArchVersion;
Expand Down Expand Up @@ -84,7 +84,11 @@ class HexagonSubtarget : public HexagonGenSubtargetInfo {
bool useMemOps() const { return UseMemOps; }
bool hasV5TOps() const { return getHexagonArchVersion() >= V5; }
bool hasV5TOpsOnly() const { return getHexagonArchVersion() == V5; }
bool hasV60TOps() const { return getHexagonArchVersion() >= V60; }
bool hasV60TOpsOnly() const { return getHexagonArchVersion() == V60; }
bool modeIEEERndNear() const { return ModeIEEERndNear; }
bool useHVXDblOps() const { return UseHVXDblOps; }
bool useHVXSglOps() const { return UseHVXOps && !UseHVXDblOps; }
bool enableMachineScheduler() const override;
// Always use the TargetLowering default scheduler.
// FIXME: This will use the vliw scheduler which is probably just hurting
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,34 @@ void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
O << -1;
}

void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const {
int64_t Imm = MI->getOperand(OpNo).getImm();
assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
O << formatImm(Imm/64);
}

void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const {
int64_t Imm = MI->getOperand(OpNo).getImm();
assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
O << formatImm(Imm/128);
}

void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const {
int64_t Imm = MI->getOperand(OpNo).getImm();
assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
O << formatImm(Imm/64);
}

void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const {
int64_t Imm = MI->getOperand(OpNo).getImm();
assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
O << formatImm(Imm/128);
}

void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
const MCOperand& MO0 = MI->getOperand(OpNo);
Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ namespace llvm {
void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
const;
void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
const;
const;
void prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const;
void prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const;
void prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const;
void prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
raw_ostream &O) const;
void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
const;
void printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/Generic/MachineBranchProb.ll
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
; RUN: llc < %s -print-machineinstrs=expand-isel-pseudos -o /dev/null 2>&1 | FileCheck %s

; ARM & AArch64 run an extra SimplifyCFG which disrupts this test.
; Hexagon crashes (PR23377)
; XFAIL: arm,aarch64,hexagon
; XFAIL: arm,aarch64

; Make sure we have the correct weight attached to each successor.
define i32 @test2(i32 %x) nounwind uwtable readnone ssp {
Expand Down