diff options
-rw-r--r-- | lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 6 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrFormats.td | 136 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrFormatsV4.td | 27 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.cpp | 7 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.td | 2191 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfoV3.td | 51 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfoV4.td | 2962 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonSchedule.td | 31 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonScheduleV4.td | 35 |
9 files changed, 4107 insertions, 1339 deletions
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index e3520c401e..05bb4b224f 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -375,7 +375,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, }; ReplaceUses(Froms, Tos, 3); return Result_2; - } + } SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, @@ -723,7 +723,7 @@ SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { if (AM != ISD::UNINDEXED) { return SelectIndexedStore(ST, dl); } - + return SelectBaseOffsetStore(ST, dl); } @@ -1215,7 +1215,7 @@ SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) { // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that // Rd and Rd' are assigned to the same register - SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_rr_acc, dl, MVT::i32, + SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32, N->getOperand(1), Src1->getOperand(0), Src1->getOperand(1)); diff --git a/lib/Target/Hexagon/HexagonInstrFormats.td b/lib/Target/Hexagon/HexagonInstrFormats.td index c9f16fb538..867a579a89 100644 --- a/lib/Target/Hexagon/HexagonInstrFormats.td +++ b/lib/Target/Hexagon/HexagonInstrFormats.td @@ -13,29 +13,48 @@ // *** Must match HexagonBaseInfo.h *** //===----------------------------------------------------------------------===// +class Type<bits<5> t> { + bits<5> Value = t; +} +def TypePSEUDO : Type<0>; +def TypeALU32 : Type<1>; +def TypeCR : Type<2>; +def TypeJR : Type<3>; +def TypeJ : Type<4>; +def TypeLD : Type<5>; +def TypeST : Type<6>; +def TypeSYSTEM : Type<7>; +def TypeXTYPE : Type<8>; +def TypeMARKER : Type<31>; //===----------------------------------------------------------------------===// // Intruction Class Declaration + //===----------------------------------------------------------------------===// class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr, InstrItinClass itin> : Instruction { + string cstr, InstrItinClass itin, Type type> : Instruction { field bits<32> Inst; let Namespace = "Hexagon"; dag OutOperandList = outs; dag InOperandList = ins; - let AsmString = asmstr; + let AsmString = asmstr; let Pattern = pattern; let Constraints = cstr; - let Itinerary = itin; - - // *** The code below must match HexagonBaseInfo.h *** - + let Itinerary = itin; + let Size = 4; + + // *** Must match HexagonBaseInfo.h *** + // Instruction type according to the ISA. + Type HexagonType = type; + let TSFlags{4-0} = HexagonType.Value; + // Solo instructions, i.e., those that cannot be in a packet with others. + bits<1> isHexagonSolo = 0; + let TSFlags{5} = isHexagonSolo; // Predicated instructions. bits<1> isPredicated = 0; - let TSFlags{1} = isPredicated; + let TSFlags{6} = isPredicated; // *** The code above must match HexagonBaseInfo.h *** } @@ -47,17 +66,25 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern, // LD Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class LDInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", LD> { + : InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> { bits<5> rd; bits<5> rs; bits<13> imm13; } +class LDInst2<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> { + bits<5> rd; + bits<5> rs; + bits<13> imm13; + let mayLoad = 1; +} + // LD Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, LD> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, LD, TypeLD> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -68,7 +95,24 @@ class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, // ST Instruction Class in V4 can take SLOT0 & SLOT1. // Definition of the instruction class CHANGED from V2/V3 to V4. class STInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ST> { + : InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> { + bits<5> rd; + bits<5> rs; + bits<13> imm13; +} + +class STInst2<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> { + bits<5> rd; + bits<5> rs; + bits<13> imm13; + let mayStore = 1; +} + +// SYSTEM Instruction Class in V4 can take SLOT0 only +// In V2/V3 we used ST for this but in v4 ST can take SLOT0 or SLOT1. +class SYSInst<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstHexagon<outs, ins, asmstr, pattern, "", SYS, TypeSYSTEM> { bits<5> rd; bits<5> rs; bits<13> imm13; @@ -79,7 +123,7 @@ class STInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class CHANGED from V2/V3 to V4. class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, ST> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, ST, TypeST> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -89,7 +133,7 @@ class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern, // ALU32 Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ALU32> { + : InstHexagon<outs, ins, asmstr, pattern, "", ALU32, TypeALU32> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -102,7 +146,17 @@ class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from ALU64 to XTYPE from V2/V3 to V4. class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", ALU64> { + : InstHexagon<outs, ins, asmstr, pattern, "", ALU64, TypeXTYPE> { + bits<5> rd; + bits<5> rs; + bits<5> rt; + bits<16> imm16; + bits<16> imm16_2; +} + +class ALU64_acc<dag outs, dag ins, string asmstr, list<dag> pattern, + string cstr> + : InstHexagon<outs, ins, asmstr, pattern, cstr, ALU64, TypeXTYPE> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -115,7 +169,7 @@ class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4. class MInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", M> { + : InstHexagon<outs, ins, asmstr, pattern, "", M, TypeXTYPE> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -126,8 +180,8 @@ class MInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4. class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, M> { + string cstr> + : InstHexagon<outs, ins, asmstr, pattern, cstr, M, TypeXTYPE> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -138,9 +192,7 @@ class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4. class SInst<dag outs, dag ins, string asmstr, list<dag> pattern> -//: InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, M)> { - : InstHexagon<outs, ins, asmstr, pattern, "", S> { -// : InstHexagon<outs, ins, asmstr, pattern, "", S> { + : InstHexagon<outs, ins, asmstr, pattern, "", S, TypeXTYPE> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -151,8 +203,8 @@ class SInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of the instruction class NOT CHANGED. // Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4. class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, - string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, S> { + string cstr> + : InstHexagon<outs, ins, asmstr, pattern, cstr, S, TypeXTYPE> { // : InstHexagon<outs, ins, asmstr, pattern, cstr, S> { // : InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, S)> { bits<5> rd; @@ -163,14 +215,14 @@ class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern, // J Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class JType<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", J> { + : InstHexagon<outs, ins, asmstr, pattern, "", J, TypeJ> { bits<16> imm16; } // JR Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class JRType<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", JR> { + : InstHexagon<outs, ins, asmstr, pattern, "", JR, TypeJR> { bits<5> rs; bits<5> pu; // Predicate register } @@ -178,15 +230,22 @@ class JRType<dag outs, dag ins, string asmstr, list<dag> pattern> // CR Instruction Class in V2/V3/V4. // Definition of the instruction class NOT CHANGED. class CRInst<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", CR> { + : InstHexagon<outs, ins, asmstr, pattern, "", CR, TypeCR> { bits<5> rs; bits<10> imm10; } +class Marker<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstHexagon<outs, ins, asmstr, pattern, "", MARKER, TypeMARKER> { + let isCodeGenOnly = 1; + let isPseudo = 1; +} class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO>; - + : InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO, TypePSEUDO> { + let isCodeGenOnly = 1; + let isPseudo = 1; +} //===----------------------------------------------------------------------===// // Intruction Classes Definitions - @@ -222,6 +281,11 @@ class ALU64_rr<dag outs, dag ins, string asmstr, list<dag> pattern> : ALU64Type<outs, ins, asmstr, pattern> { } +class ALU64_ri<dag outs, dag ins, string asmstr, list<dag> pattern> + : ALU64Type<outs, ins, asmstr, pattern> { + let rt{0-4} = 0; +} + // J Type Instructions. class JInst<dag outs, dag ins, string asmstr, list<dag> pattern> : JType<outs, ins, asmstr, pattern> { @@ -234,15 +298,31 @@ class JRInst<dag outs, dag ins, string asmstr, list<dag> pattern> // Post increment ST Instruction. -class STInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> +class STInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, + string cstr> + : STInstPost<outs, ins, asmstr, pattern, cstr> { + let rt{0-4} = 0; +} + +class STInst2PI<dag outs, dag ins, string asmstr, list<dag> pattern, + string cstr> : STInstPost<outs, ins, asmstr, pattern, cstr> { let rt{0-4} = 0; + let mayStore = 1; } // Post increment LD Instruction. -class LDInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> +class LDInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, + string cstr> + : LDInstPost<outs, ins, asmstr, pattern, cstr> { + let rt{0-4} = 0; +} + +class LDInst2PI<dag outs, dag ins, string asmstr, list<dag> pattern, + string cstr> : LDInstPost<outs, ins, asmstr, pattern, cstr> { let rt{0-4} = 0; + let mayLoad = 1; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/lib/Target/Hexagon/HexagonInstrFormatsV4.td index bd5e4493d7..49741a3d1b 100644 --- a/lib/Target/Hexagon/HexagonInstrFormatsV4.td +++ b/lib/Target/Hexagon/HexagonInstrFormatsV4.td @@ -11,11 +11,25 @@ // //===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// +// Hexagon Intruction Flags + +// +// *** Must match BaseInfo.h *** +//----------------------------------------------------------------------------// + +def TypeMEMOP : Type<9>; +def TypeNV : Type<10>; +def TypePREFIX : Type<30>; + +//----------------------------------------------------------------------------// +// Intruction Classes Definitions + +//----------------------------------------------------------------------------// + // // NV type instructions. // class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", NV_V4> { + : InstHexagon<outs, ins, asmstr, pattern, "", NV_V4, TypeNV> { bits<5> rd; bits<5> rs; bits<13> imm13; @@ -24,7 +38,7 @@ class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> // Definition of Post increment new value store. class NVInstPost_V4<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr> - : InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4> { + : InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4, TypeNV> { bits<5> rd; bits<5> rs; bits<5> rt; @@ -39,8 +53,15 @@ class NVInstPI_V4<dag outs, dag ins, string asmstr, list<dag> pattern, } class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern> - : InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4> { + : InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4, TypeMEMOP> { bits<5> rd; bits<5> rs; bits<6> imm6; } + +class Immext<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX> { + let isCodeGenOnly = 1; + + bits<26> imm26; +} diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index a3918692db..641835637f 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1200,9 +1200,6 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { case Hexagon::LDriub: return !invertPredicate ? Hexagon::LDriub_cPt : Hexagon::LDriub_cNotPt; - case Hexagon::LDriubit: - return !invertPredicate ? Hexagon::LDriub_cPt : - Hexagon::LDriub_cNotPt; // Load Indexed. case Hexagon::LDrid_indexed: return !invertPredicate ? Hexagon::LDrid_indexed_cPt : @@ -1409,7 +1406,6 @@ isValidOffset(const int Opcode, const int Offset) const { case Hexagon::LDrih: case Hexagon::LDriuh: case Hexagon::STrih: - case Hexagon::LDrih_ae: assert((Offset % 2 == 0) && "Offset has incorrect alignment"); return (Offset >= Hexagon_MEMH_OFFSET_MIN) && (Offset <= Hexagon_MEMH_OFFSET_MAX); @@ -1417,9 +1413,6 @@ isValidOffset(const int Opcode, const int Offset) const { case Hexagon::LDrib: case Hexagon::STrib: case Hexagon::LDriub: - case Hexagon::LDriubit: - case Hexagon::LDrib_ae: - case Hexagon::LDriub_ae: return (Offset >= Hexagon_MEMB_OFFSET_MIN) && (Offset <= Hexagon_MEMB_OFFSET_MAX); diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index b563ac3c61..9e5c7e548b 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -84,10 +84,12 @@ def symbolLo32 : Operand<i32> { multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> { def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set IntRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>; + [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b), + (i32 IntRegs:$c)))]>; def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")), - [(set IntRegs:$dst, (OpNode s10Imm:$b, IntRegs:$c))]>; + [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b, + (i32 IntRegs:$c)))]>; } // Multi-class for compare ops. @@ -95,111 +97,114 @@ let isCompare = 1 in { multiclass CMP64_rr<string OpcStr, PatFrag OpNode> { def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set PredRegs:$dst, (OpNode DoubleRegs:$b, DoubleRegs:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>; } multiclass CMP32_rr<string OpcStr, PatFrag OpNode> { def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; } multiclass CMP32_rr_ri_s10<string OpcStr, PatFrag OpNode> { def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Imm:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, s10ImmPred:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i32 IntRegs:$b), s10ImmPred:$c))]>; } multiclass CMP32_rr_ri_u9<string OpcStr, PatFrag OpNode> { def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Imm:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, u9ImmPred:$c))]>; + [(set (i1 PredRegs:$dst), + (OpNode (i32 IntRegs:$b), u9ImmPred:$c))]>; } -multiclass CMP32_ri_u9<string OpcStr, PatFrag OpNode> { - def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Imm:$c), +multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> { + def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Imm:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, u9ImmPred:$c))]>; + [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), + u8ImmPred:$c))]>; } multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> { def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Imm:$c), !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set PredRegs:$dst, (OpNode IntRegs:$b, s8ImmPred:$c))]>; + [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), + s8ImmPred:$c))]>; } } //===----------------------------------------------------------------------===// -// Instructions -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// http://qualnet.qualcomm.com/~erich/v1/htmldocs/index.html -// http://qualnet.qualcomm.com/~erich/v2/htmldocs/index.html -// http://qualnet.qualcomm.com/~erich/v3/htmldocs/index.html -// http://qualnet.qualcomm.com/~erich/v4/htmldocs/index.html -// http://qualnet.qualcomm.com/~erich/v5/htmldocs/index.html -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// // ALU32/ALU + //===----------------------------------------------------------------------===// // Add. -let isPredicable = 1 in +let isCommutable = 1, isPredicable = 1 in def ADD_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = add($src1, $src2)", - [(set IntRegs:$dst, (add IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1), + (i32 IntRegs:$src2)))]>; let isPredicable = 1 in def ADD_ri : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1, s16Imm:$src2), "$dst = add($src1, #$src2)", - [(set IntRegs:$dst, (add IntRegs:$src1, s16ImmPred:$src2))]>; + [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1), + s16ImmPred:$src2))]>; // Logical operations. let isPredicable = 1 in def XOR_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = xor($src1, $src2)", - [(set IntRegs:$dst, (xor IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1), + (i32 IntRegs:$src2)))]>; -let isPredicable = 1 in +let isCommutable = 1, isPredicable = 1 in def AND_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = and($src1, $src2)", - [(set IntRegs:$dst, (and IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), + (i32 IntRegs:$src2)))]>; def OR_ri : ALU32_ri<(outs IntRegs:$dst), - (ins IntRegs:$src1, s8Imm:$src2), + (ins IntRegs:$src1, s10Imm:$src2), "$dst = or($src1, #$src2)", - [(set IntRegs:$dst, (or IntRegs:$src1, s8ImmPred:$src2))]>; + [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), + s10ImmPred:$src2))]>; def NOT_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = not($src1)", - [(set IntRegs:$dst, (not IntRegs:$src1))]>; + [(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>; def AND_ri : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1, s10Imm:$src2), "$dst = and($src1, #$src2)", - [(set IntRegs:$dst, (and IntRegs:$src1, s10ImmPred:$src2))]>; + [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), + s10ImmPred:$src2))]>; -let isPredicable = 1 in +let isCommutable = 1, isPredicable = 1 in def OR_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = or($src1, $src2)", - [(set IntRegs:$dst, (or IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), + (i32 IntRegs:$src2)))]>; // Negate. def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = neg($src1)", - [(set IntRegs:$dst, (ineg IntRegs:$src1))]>; + [(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>; // Nop. let neverHasSideEffects = 1 in def NOP : ALU32_rr<(outs), (ins), @@ -211,13 +216,20 @@ let isPredicable = 1 in def SUB_rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = sub($src1, $src2)", - [(set IntRegs:$dst, (sub IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1), + (i32 IntRegs:$src2)))]>; + +// Rd32=sub(#s10,Rs32) +def SUB_ri : ALU32_ri<(outs IntRegs:$dst), + (ins s10Imm:$src1, IntRegs:$src2), + "$dst = sub(#$src1, $src2)", + [(set IntRegs:$dst, (sub s10ImmPred:$src1, IntRegs:$src2))]>; // Transfer immediate. -let isReMaterializable = 1, isPredicable = 1 in +let isMoveImm = 1, isReMaterializable = 1, isPredicable = 1 in def TFRI : ALU32_ri<(outs IntRegs:$dst), (ins s16Imm:$src1), "$dst = #$src1", - [(set IntRegs:$dst, s16ImmPred:$src1)]>; + [(set (i32 IntRegs:$dst), s16ImmPred:$src1)]>; // Transfer register. let neverHasSideEffects = 1, isPredicable = 1 in @@ -225,6 +237,12 @@ def TFR : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = $src1", []>; +let neverHasSideEffects = 1, isPredicable = 1 in +def TFR64 : ALU32_ri<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), + "$dst = $src1", + []>; + + // Transfer control register. let neverHasSideEffects = 1 in def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1), @@ -246,6 +264,12 @@ def COMBINE_rr : ALU32_rr<(outs DoubleRegs:$dst), "$dst = combine($src1, $src2)", []>; +let neverHasSideEffects = 1 in +def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst), + (ins s8Imm:$src1, s8Imm:$src2), + "$dst = combine(#$src1, #$src2)", + []>; + // Mux. def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, DoubleRegs:$src2, @@ -256,48 +280,52 @@ def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "$dst = mux($src1, $src2, $src3)", - [(set IntRegs:$dst, (select PredRegs:$src1, IntRegs:$src2, - IntRegs:$src3))]>; + [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), + (i32 IntRegs:$src2), + (i32 IntRegs:$src3))))]>; def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Imm:$src2, IntRegs:$src3), "$dst = mux($src1, #$src2, $src3)", - [(set IntRegs:$dst, (select PredRegs:$src1, - s8ImmPred:$src2, IntRegs:$src3))]>; + [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), + s8ImmPred:$src2, + (i32 IntRegs:$src3))))]>; def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3), "$dst = mux($src1, $src2, #$src3)", - [(set IntRegs:$dst, (select PredRegs:$src1, IntRegs:$src2, - s8ImmPred:$src3))]>; + [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), + (i32 IntRegs:$src2), + s8ImmPred:$src3)))]>; def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Imm:$src2, s8Imm:$src3), "$dst = mux($src1, #$src2, #$src3)", - [(set IntRegs:$dst, (select PredRegs:$src1, s8ImmPred:$src2, - s8ImmPred:$src3))]>; + [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), + s8ImmPred:$src2, + s8ImmPred:$src3)))]>; // Shift halfword. let isPredicable = 1 in def ASLH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = aslh($src1)", - [(set IntRegs:$dst, (shl 16, IntRegs:$src1))]>; + [(set (i32 IntRegs:$dst), (shl 16, (i32 IntRegs:$src1)))]>; let isPredicable = 1 in def ASRH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = asrh($src1)", - [(set IntRegs:$dst, (sra 16, IntRegs:$src1))]>; + [(set (i32 IntRegs:$dst), (sra 16, (i32 IntRegs:$src1)))]>; // Sign extend. let isPredicable = 1 in def SXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = sxtb($src1)", - [(set IntRegs:$dst, (sext_inreg IntRegs:$src1, i8))]>; + [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i8))]>; let isPredicable = 1 in def SXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = sxth($src1)", - [(set IntRegs:$dst, (sext_inreg IntRegs:$src1, i16))]>; + [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i16))]>; // Zero extend. let isPredicable = 1, neverHasSideEffects = 1 in @@ -321,25 +349,25 @@ def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), // Conditional add. let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cPt : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), + (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3), "if ($src1) $dst = add($src2, #$src3)", []>; let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cNotPt : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), + (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3), "if (!$src1) $dst = add($src2, #$src3)", []>; let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cdnPt : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), + (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3), "if ($src1.new) $dst = add($src2, #$src3)", []>; let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cdnNotPt : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), + (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3), "if (!$src1.new) $dst = add($src2, #$src3)", []>; @@ -497,7 +525,6 @@ def SUB_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), // Conditional transfer. - let neverHasSideEffects = 1, isPredicated = 1 in def TFR_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = $src2", @@ -510,6 +537,18 @@ def TFR_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, []>; let neverHasSideEffects = 1, isPredicated = 1 in +def TFR64_cPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, + DoubleRegs:$src2), + "if ($src1) $dst = $src2", + []>; + +let neverHasSideEffects = 1, isPredicated = 1 in +def TFR64_cNotPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, + DoubleRegs:$src2), + "if (!$src1) $dst = $src2", + []>; + +let neverHasSideEffects = 1, isPredicated = 1 in def TFRI_cPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2), "if ($src1) $dst = #$src2", []>; @@ -548,25 +587,14 @@ def TFRI_cdnNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", setugt>; defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", setgt>; defm CMPLT : CMP32_rr<"cmp.lt", setlt>; +defm CMPLTU : CMP32_rr<"cmp.ltu", setult>; defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", seteq>; defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>; -defm CMPGEU : CMP32_ri_u9<"cmp.geu", setuge>; +defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>; //===----------------------------------------------------------------------===// // ALU32/PRED - //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// ALU32/VH + -//===----------------------------------------------------------------------===// -// Vector add halfwords - -// Vector averagehalfwords - -// Vector subtract halfwords -//===----------------------------------------------------------------------===// -// ALU32/VH - -//===----------------------------------------------------------------------===// - //===----------------------------------------------------------------------===// // ALU64/ALU + @@ -575,8 +603,8 @@ defm CMPGEU : CMP32_ri_u9<"cmp.geu", setuge>; def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = add($src1, $src2)", - [(set DoubleRegs:$dst, (add DoubleRegs:$src1, - DoubleRegs:$src2))]>; + [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1), + (i64 DoubleRegs:$src2)))]>; // Add halfword. @@ -589,40 +617,93 @@ defm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>; def AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = and($src1, $src2)", - [(set DoubleRegs:$dst, (and DoubleRegs:$src1, - DoubleRegs:$src2))]>; + [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), + (i64 DoubleRegs:$src2)))]>; def OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = or($src1, $src2)", - [(set DoubleRegs:$dst, (or DoubleRegs:$src1, DoubleRegs:$src2))]>; + [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1), + (i64 DoubleRegs:$src2)))]>; def XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = xor($src1, $src2)", - [(set DoubleRegs:$dst, (xor DoubleRegs:$src1, - DoubleRegs:$src2))]>; + [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), + (i64 DoubleRegs:$src2)))]>; // Maximum. def MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), "$dst = max($src2, $src1)", - [(set IntRegs:$dst, (select (i1 (setlt IntRegs:$src2, - IntRegs:$src1)), - IntRegs:$src1, IntRegs:$src2))]>; + [(set (i32 IntRegs:$dst), + (i32 (select (i1 (setlt (i32 IntRegs:$src2), + (i32 IntRegs:$src1))), + (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; + +def MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs |