xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonPseudo.td (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric//===--- HexagonPseudo.td -------------------------------------------------===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric// The pat frags in the definitions below need to have a named register,
100b57cec5SDimitry Andric// otherwise i32 will be assumed regardless of the register class. The
110b57cec5SDimitry Andric// name of the register does not matter.
120b57cec5SDimitry Andricdef I1  : PatLeaf<(i1 PredRegs:$R)>;
130b57cec5SDimitry Andricdef I32 : PatLeaf<(i32 IntRegs:$R)>;
140b57cec5SDimitry Andricdef I64 : PatLeaf<(i64 DoubleRegs:$R)>;
150b57cec5SDimitry Andricdef F32 : PatLeaf<(f32 IntRegs:$R)>;
160b57cec5SDimitry Andricdef F64 : PatLeaf<(f64 DoubleRegs:$R)>;
170b57cec5SDimitry Andric
180b57cec5SDimitry Andriclet PrintMethod = "printGlobalOperand" in {
190b57cec5SDimitry Andric  def globaladdress : Operand<i32>;
200b57cec5SDimitry Andric  def globaladdressExt : Operand<i32>;
210b57cec5SDimitry Andric}
220b57cec5SDimitry Andric
230b57cec5SDimitry Andriclet isPseudo = 1 in {
240b57cec5SDimitry Andriclet isCodeGenOnly = 0 in
250b57cec5SDimitry Andricdef A2_iconst : Pseudo<(outs IntRegs:$Rd32),
260b57cec5SDimitry Andric    (ins s27_2Imm:$Ii), "${Rd32} = iconst(#${Ii})">;
270b57cec5SDimitry Andric
280b57cec5SDimitry Andricdef DUPLEX_Pseudo : InstHexagon<(outs),
290b57cec5SDimitry Andric    (ins s32_0Imm:$offset), "DUPLEX", [], "", DUPLEX, TypePSEUDO>;
300b57cec5SDimitry Andric}
310b57cec5SDimitry Andric
320b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 1, opExtentBits = 6,
330b57cec5SDimitry Andric    isAsmParserOnly = 1 in
340b57cec5SDimitry Andricdef TFRI64_V2_ext : InstHexagon<(outs DoubleRegs:$dst),
350b57cec5SDimitry Andric    (ins s32_0Imm:$src1, s8_0Imm:$src2),
360b57cec5SDimitry Andric    "$dst = combine(#$src1,#$src2)", [], "",
370b57cec5SDimitry Andric    A2_combineii.Itinerary, TypeALU32_2op>, OpcodeHexagon;
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric// HI/LO Instructions
400b57cec5SDimitry Andriclet isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0,
410b57cec5SDimitry Andric    hasNewValue = 1, opNewValue = 0 in
420b57cec5SDimitry Andricclass REG_IMMED<string RegHalf, bit Rs, bits<3> MajOp, bit MinOp,
430b57cec5SDimitry Andric                InstHexagon rootInst>
440b57cec5SDimitry Andric  : InstHexagon<(outs IntRegs:$dst),
450b57cec5SDimitry Andric                (ins u16_0Imm:$imm_value),
460b57cec5SDimitry Andric                "$dst"#RegHalf#" = #$imm_value", [], "",
470b57cec5SDimitry Andric                rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
480b57cec5SDimitry Andric    bits<5> dst;
490b57cec5SDimitry Andric    bits<32> imm_value;
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric    let Inst{27} = Rs;
520b57cec5SDimitry Andric    let Inst{26-24} = MajOp;
530b57cec5SDimitry Andric    let Inst{21} = MinOp;
540b57cec5SDimitry Andric    let Inst{20-16} = dst;
550b57cec5SDimitry Andric    let Inst{23-22} = imm_value{15-14};
560b57cec5SDimitry Andric    let Inst{13-0} = imm_value{13-0};
570b57cec5SDimitry Andric}
580b57cec5SDimitry Andric
590b57cec5SDimitry Andriclet isAsmParserOnly = 1 in {
600b57cec5SDimitry Andric  def LO : REG_IMMED<".l", 0b0, 0b001, 0b1, A2_tfril>;
610b57cec5SDimitry Andric  def HI : REG_IMMED<".h", 0b0, 0b010, 0b1, A2_tfrih>;
620b57cec5SDimitry Andric}
630b57cec5SDimitry Andric
640b57cec5SDimitry Andriclet isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in {
650b57cec5SDimitry Andric  def CONST32 : CONSTLDInst<(outs IntRegs:$Rd), (ins i32imm:$v),
660b57cec5SDimitry Andric                "$Rd = CONST32(#$v)", []>;
670b57cec5SDimitry Andric  def CONST64 : CONSTLDInst<(outs DoubleRegs:$Rd), (ins i64imm:$v),
680b57cec5SDimitry Andric                "$Rd = CONST64(#$v)", []>;
690b57cec5SDimitry Andric}
700b57cec5SDimitry Andric
710b57cec5SDimitry Andriclet hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
720b57cec5SDimitry Andric    isCodeGenOnly = 1 in
730b57cec5SDimitry Andricdef PS_true : InstHexagon<(outs PredRegs:$dst), (ins), "",
740b57cec5SDimitry Andric              [(set I1:$dst, 1)], "", C2_orn.Itinerary, TypeCR>;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andriclet hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
770b57cec5SDimitry Andric    isCodeGenOnly = 1 in
780b57cec5SDimitry Andricdef PS_false : InstHexagon<(outs PredRegs:$dst), (ins), "",
790b57cec5SDimitry Andric               [(set I1:$dst, 0)], "", C2_andn.Itinerary, TypeCR>;
800b57cec5SDimitry Andric
810b57cec5SDimitry Andriclet Defs = [R29, R30], Uses = [R31, R30, R29], isPseudo = 1 in
820b57cec5SDimitry Andricdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
830b57cec5SDimitry Andric                              ".error \"should not emit\" ", []>;
840b57cec5SDimitry Andric
850b57cec5SDimitry Andriclet Defs = [R29, R30, R31], Uses = [R29], isPseudo = 1 in
860b57cec5SDimitry Andricdef ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
870b57cec5SDimitry Andric                             ".error \"should not emit\" ", []>;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric
900b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, hasSideEffects = 0,
910b57cec5SDimitry Andric    Defs = [PC, LC0], Uses = [SA0, LC0] in {
920b57cec5SDimitry Andricdef ENDLOOP0 : Endloop<(outs), (ins b30_2Imm:$offset),
930b57cec5SDimitry Andric                       ":endloop0",
940b57cec5SDimitry Andric                       []>;
950b57cec5SDimitry Andric}
960b57cec5SDimitry Andric
970b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, hasSideEffects = 0,
980b57cec5SDimitry Andric    Defs = [PC, LC1], Uses = [SA1, LC1] in {
990b57cec5SDimitry Andricdef ENDLOOP1 : Endloop<(outs), (ins b30_2Imm:$offset),
1000b57cec5SDimitry Andric                       ":endloop1",
1010b57cec5SDimitry Andric                       []>;
1020b57cec5SDimitry Andric}
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, hasSideEffects = 0,
1050b57cec5SDimitry Andric    Defs = [PC, LC0, LC1], Uses = [SA0, SA1, LC0, LC1] in {
1060b57cec5SDimitry Andricdef ENDLOOP01 : Endloop<(outs), (ins b30_2Imm:$offset),
1070b57cec5SDimitry Andric                        ":endloop01",
1080b57cec5SDimitry Andric                        []>;
1090b57cec5SDimitry Andric}
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andriclet isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
1120b57cec5SDimitry Andric    opExtendable = 0, hasSideEffects = 0 in
1130b57cec5SDimitry Andricclass LOOP_iBase<string mnemonic, InstHexagon rootInst>
1140b57cec5SDimitry Andric         : InstHexagon <(outs), (ins b30_2Imm:$offset, u10_0Imm:$src2),
1155ffd83dbSDimitry Andric           mnemonic#"($offset,#$src2)",
1160b57cec5SDimitry Andric           [], "", rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
1170b57cec5SDimitry Andric    bits<9> offset;
1180b57cec5SDimitry Andric    bits<10> src2;
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric    let IClass = 0b0110;
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric    let Inst{27-22} = 0b100100;
1230b57cec5SDimitry Andric    let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
1240b57cec5SDimitry Andric    let Inst{20-16} = src2{9-5};
1250b57cec5SDimitry Andric    let Inst{12-8} = offset{8-4};
1260b57cec5SDimitry Andric    let Inst{7-5} = src2{4-2};
1270b57cec5SDimitry Andric    let Inst{4-3} = offset{3-2};
1280b57cec5SDimitry Andric    let Inst{1-0} = src2{1-0};
1290b57cec5SDimitry Andric}
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andriclet isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
1320b57cec5SDimitry Andric    opExtendable = 0, hasSideEffects = 0 in
1330b57cec5SDimitry Andricclass LOOP_rBase<string mnemonic, InstHexagon rootInst>
1340b57cec5SDimitry Andric         : InstHexagon<(outs), (ins b30_2Imm:$offset, IntRegs:$src2),
1355ffd83dbSDimitry Andric           mnemonic#"($offset,$src2)",
1360b57cec5SDimitry Andric           [], "", rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
1370b57cec5SDimitry Andric    bits<9> offset;
1380b57cec5SDimitry Andric    bits<5> src2;
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andric    let IClass = 0b0110;
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric    let Inst{27-22} = 0b000000;
1430b57cec5SDimitry Andric    let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
1440b57cec5SDimitry Andric    let Inst{20-16} = src2;
1450b57cec5SDimitry Andric    let Inst{12-8} = offset{8-4};
1460b57cec5SDimitry Andric    let Inst{4-3} = offset{3-2};
1470b57cec5SDimitry Andric  }
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andriclet Defs = [SA0, LC0, USR], isCodeGenOnly = 1, isExtended = 1,
1500b57cec5SDimitry Andric    opExtendable = 0 in {
1510b57cec5SDimitry Andric  def J2_loop0iext : LOOP_iBase<"loop0", J2_loop0i>;
1520b57cec5SDimitry Andric  def J2_loop1iext : LOOP_iBase<"loop1", J2_loop1i>;
1530b57cec5SDimitry Andric}
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric// Interestingly only loop0's appear to set usr.lpcfg
1560b57cec5SDimitry Andriclet Defs = [SA1, LC1], isCodeGenOnly = 1, isExtended = 1, opExtendable = 0 in {
1570b57cec5SDimitry Andric  def J2_loop0rext : LOOP_rBase<"loop0", J2_loop0r>;
1580b57cec5SDimitry Andric  def J2_loop1rext : LOOP_rBase<"loop1", J2_loop1r>;
1590b57cec5SDimitry Andric}
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andriclet isCall = 1, hasSideEffects = 1, isPredicable = 0,
1620b57cec5SDimitry Andric    isExtended = 0, isExtendable = 1, opExtendable = 0,
1630b57cec5SDimitry Andric    isExtentSigned = 1, opExtentBits = 24, opExtentAlign = 2 in
1640b57cec5SDimitry Andricclass T_Call<string ExtStr>
1650b57cec5SDimitry Andric  : InstHexagon<(outs), (ins a30_2Imm:$dst),
1660b57cec5SDimitry Andric      "call " # ExtStr # "$dst", [], "", J2_call.Itinerary, TypeJ>,
1670b57cec5SDimitry Andric    OpcodeHexagon {
1680b57cec5SDimitry Andric  let BaseOpcode = "call";
1690b57cec5SDimitry Andric  bits<24> dst;
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric  let IClass = 0b0101;
1720b57cec5SDimitry Andric  let Inst{27-25} = 0b101;
1730b57cec5SDimitry Andric  let Inst{24-16,13-1} = dst{23-2};
1740b57cec5SDimitry Andric  let Inst{0} = 0b0;
1750b57cec5SDimitry Andric}
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andriclet isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1, Defs = [R16],
1780b57cec5SDimitry Andric    isPredicable = 0 in
1790b57cec5SDimitry Andricdef CALLProfile :  T_Call<"">;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andriclet isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1,
1820b57cec5SDimitry Andric    Defs = [PC, R31, R6, R7, P0] in
1830b57cec5SDimitry Andricdef PS_call_stk : T_Call<"">;
1840b57cec5SDimitry Andric
18581ad6265SDimitry Andric// This pseudo instruction is used to replace int_hexagon_instrprof_custom intrinsic
18681ad6265SDimitry Andric// with a call to custom handler passed as the first argument to the intrinsic.
18781ad6265SDimitry Andric
18881ad6265SDimitry Andric// Pleae Note:
18981ad6265SDimitry Andric// 1) The call to the custom handler is being treated as a special one as the
19081ad6265SDimitry Andric//    callee is responsible for saving and restoring all the registers it needs
19181ad6265SDimitry Andric//    to modify. This includes caller saved registers as well as r0-r5 argument
19281ad6265SDimitry Andric//    registers. This is done to reduce the impact of instrumentation on the
19381ad6265SDimitry Andric//    code being instrumented/profiled.
19481ad6265SDimitry Andric// 2) R14, R15 and R28 are reserved for PLT handling and therefore are
19581ad6265SDimitry Andric//    part of the def list.
19681ad6265SDimitry Andric// 3) R0 is used to pass the unique id associated with an instrumentation site
19781ad6265SDimitry Andric//    to the handler.
19881ad6265SDimitry Andric// 4) All the other registers (R29, R30, R31, PC) get modified by the call
19981ad6265SDimitry Andric//    instruction.
20081ad6265SDimitry Andric
20181ad6265SDimitry Andric// TODO: It may be a good idea to add a separate pseudo instruction for
20281ad6265SDimitry Andric// static relocation which doesn't need to reserve r14, r15 and r28.
20381ad6265SDimitry Andric
20481ad6265SDimitry Andriclet hasSideEffects = 1, isCall = 1, Defs = [R0, R14, R15, R28, R29, R30, R31, PC] in
20581ad6265SDimitry Andricdef PS_call_instrprof_custom :  Pseudo<(outs), (ins s32_0Imm:$dst, u32_0Imm:$Ii), "">;
20681ad6265SDimitry Andric
2070b57cec5SDimitry Andric// Call, no return.
2080b57cec5SDimitry Andriclet isCall = 1, hasSideEffects = 1, cofMax1 = 1, isCodeGenOnly = 1 in
2090b57cec5SDimitry Andricdef PS_callr_nr: InstHexagon<(outs), (ins IntRegs:$Rs),
2100b57cec5SDimitry Andric    "callr $Rs", [], "", J2_callr.Itinerary, TypeJ>, OpcodeHexagon {
2110b57cec5SDimitry Andric    bits<5> Rs;
2120b57cec5SDimitry Andric    bits<2> Pu;
2130b57cec5SDimitry Andric    let isPredicatedFalse = 1;
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric    let IClass = 0b0101;
2160b57cec5SDimitry Andric    let Inst{27-21} = 0b0000101;
2170b57cec5SDimitry Andric    let Inst{20-16} = Rs;
2180b57cec5SDimitry Andric  }
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andriclet isCall = 1, hasSideEffects = 1,
2210b57cec5SDimitry Andric    isExtended = 0, isExtendable = 1, opExtendable = 0, isCodeGenOnly = 1,
2220b57cec5SDimitry Andric    BaseOpcode = "PS_call_nr", isExtentSigned = 1, opExtentAlign = 2 in
223349cc55cSDimitry Andricclass Call_nr<bits<5> nbits, bit isFalse, dag iops,
2240b57cec5SDimitry Andric              InstrItinClass itin>
2250b57cec5SDimitry Andric  : Pseudo<(outs), iops, "">, PredRel {
2260b57cec5SDimitry Andric    bits<2> Pu;
2270b57cec5SDimitry Andric    bits<17> dst;
2280b57cec5SDimitry Andric    let opExtentBits = nbits;
2290b57cec5SDimitry Andric    let isPredicable = 0;  // !if(isPred, 0, 1);
2300b57cec5SDimitry Andric    let isPredicated = 0;  // isPred;
2310b57cec5SDimitry Andric    let isPredicatedFalse = isFalse;
2320b57cec5SDimitry Andric    let Itinerary = itin;
2330b57cec5SDimitry Andric}
2340b57cec5SDimitry Andric
235349cc55cSDimitry Andricdef PS_call_nr : Call_nr<24, 0, (ins s32_0Imm:$Ii), J2_call.Itinerary>;
2360b57cec5SDimitry Andric//def PS_call_nrt: Call_nr<17, 1, 0, (ins PredRegs:$Pu, s32_0Imm:$dst),
2370b57cec5SDimitry Andric//                         J2_callt.Itinerary>;
2380b57cec5SDimitry Andric//def PS_call_nrf: Call_nr<17, 1, 1, (ins PredRegs:$Pu, s32_0Imm:$dst),
2390b57cec5SDimitry Andric//                         J2_callf.Itinerary>;
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andriclet isBranch = 1, isIndirectBranch = 1, isBarrier = 1, Defs = [PC],
2420b57cec5SDimitry Andric    isPredicable = 1, hasSideEffects = 0, InputType = "reg",
2430b57cec5SDimitry Andric    cofMax1 = 1 in
2440b57cec5SDimitry Andricclass T_JMPr <InstHexagon rootInst>
2450b57cec5SDimitry Andric  :  InstHexagon<(outs), (ins IntRegs:$dst), "jumpr $dst", [],
2460b57cec5SDimitry Andric                 "", rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
2470b57cec5SDimitry Andric    bits<5> dst;
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric    let IClass = 0b0101;
2500b57cec5SDimitry Andric    let Inst{27-21} = 0b0010100;
2510b57cec5SDimitry Andric    let Inst{20-16} = dst;
2520b57cec5SDimitry Andric}
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andric// A return through builtin_eh_return.
2550b57cec5SDimitry Andriclet isReturn = 1, isTerminator = 1, isBarrier = 1, hasSideEffects = 0,
2560b57cec5SDimitry Andric    isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
2570b57cec5SDimitry Andricdef EH_RETURN_JMPR : T_JMPr<J2_jumpr>;
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric// Indirect tail-call.
2600b57cec5SDimitry Andriclet isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
2610b57cec5SDimitry Andric    isTerminator = 1, isCodeGenOnly = 1 in
2620b57cec5SDimitry Andricdef PS_tailcall_r : T_JMPr<J2_jumpr>;
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andric//
2650b57cec5SDimitry Andric// Direct tail-calls.
2660b57cec5SDimitry Andriclet isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
2670b57cec5SDimitry Andric    isTerminator = 1, isCodeGenOnly = 1 in
2680b57cec5SDimitry Andricdef PS_tailcall_i : Pseudo<(outs), (ins a30_2Imm:$dst), "", []>;
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1, Uses = [R30], hasSideEffects = 0 in
2710b57cec5SDimitry Andricdef PS_aligna : Pseudo<(outs IntRegs:$Rd), (ins u32_0Imm:$A), "", []>;
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric// Generate frameindex addresses. The main reason for the offset operand is
2740b57cec5SDimitry Andric// that every instruction that is allowed to have frame index as an operand
2750b57cec5SDimitry Andric// will then have that operand followed by an immediate operand (the offset).
2760b57cec5SDimitry Andric// This simplifies the frame-index elimination code.
2770b57cec5SDimitry Andric//
2780b57cec5SDimitry Andriclet isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1,
2790b57cec5SDimitry Andric    isPseudo = 1, isCodeGenOnly = 1, hasSideEffects = 0, isExtendable = 1,
2800b57cec5SDimitry Andric    isExtentSigned = 1, opExtentBits = 16, opExtentAlign = 0 in {
2810b57cec5SDimitry Andric  let opExtendable = 2 in
2820b57cec5SDimitry Andric  def PS_fi  : Pseudo<(outs IntRegs:$Rd),
2830b57cec5SDimitry Andric                      (ins IntRegs:$fi, s32_0Imm:$off), "">;
2840b57cec5SDimitry Andric  let opExtendable = 3 in
2850b57cec5SDimitry Andric  def PS_fia : Pseudo<(outs IntRegs:$Rd),
2860b57cec5SDimitry Andric                      (ins IntRegs:$Rs, IntRegs:$fi, s32_0Imm:$off), "">;
2870b57cec5SDimitry Andric}
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andricclass CondStr<string CReg, bit True, bit New> {
2900b57cec5SDimitry Andric  string S = "if (" # !if(True,"","!") # CReg # !if(New,".new","") # ") ";
2910b57cec5SDimitry Andric}
292349cc55cSDimitry Andricclass JumpOpcStr<string Mnemonic, bit Taken> {
2930b57cec5SDimitry Andric  string S = Mnemonic # !if(Taken, ":t", ":nt");
2940b57cec5SDimitry Andric}
2950b57cec5SDimitry Andriclet isBranch = 1, isIndirectBranch = 1, Defs = [PC], isPredicated = 1,
2960b57cec5SDimitry Andric    hasSideEffects = 0, InputType = "reg", cofMax1 = 1 in
2970b57cec5SDimitry Andricclass T_JMPr_c <bit PredNot, bit isPredNew, bit isTak, InstHexagon rootInst>
2980b57cec5SDimitry Andric  :  InstHexagon<(outs), (ins PredRegs:$src, IntRegs:$dst),
2990b57cec5SDimitry Andric                 CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
300349cc55cSDimitry Andric                 JumpOpcStr<"jumpr", isTak>.S # " $dst",
3010b57cec5SDimitry Andric                 [], "", rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
3020b57cec5SDimitry Andric
3030b57cec5SDimitry Andric    let isTaken = isTak;
3040b57cec5SDimitry Andric    let isPredicatedFalse = PredNot;
3050b57cec5SDimitry Andric    let isPredicatedNew = isPredNew;
3060b57cec5SDimitry Andric    bits<2> src;
3070b57cec5SDimitry Andric    bits<5> dst;
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric    let IClass = 0b0101;
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric    let Inst{27-22} = 0b001101;
3120b57cec5SDimitry Andric    let Inst{21} = PredNot;
3130b57cec5SDimitry Andric    let Inst{20-16} = dst;
3140b57cec5SDimitry Andric    let Inst{12} = isTak;
3150b57cec5SDimitry Andric    let Inst{11} = isPredNew;
3160b57cec5SDimitry Andric    let Inst{9-8} = src;
3170b57cec5SDimitry Andric}
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andriclet isTerminator = 1, hasSideEffects = 0, isReturn = 1, isCodeGenOnly = 1,
3200b57cec5SDimitry Andric    isBarrier = 1, BaseOpcode = "JMPret" in {
3210b57cec5SDimitry Andric  def PS_jmpret : T_JMPr<J2_jumpr>, PredNewRel;
3220b57cec5SDimitry Andric  def PS_jmprett : T_JMPr_c<0, 0, 0, J2_jumprt>, PredNewRel;
3230b57cec5SDimitry Andric  def PS_jmpretf : T_JMPr_c<1, 0, 0, J2_jumprf>, PredNewRel;
3240b57cec5SDimitry Andric  def PS_jmprettnew : T_JMPr_c<0, 1, 0, J2_jumprtnew>, PredNewRel;
3250b57cec5SDimitry Andric  def PS_jmpretfnew : T_JMPr_c<1, 1, 0, J2_jumprfnew>, PredNewRel;
3260b57cec5SDimitry Andric  def PS_jmprettnewpt : T_JMPr_c<0, 1, 1, J2_jumprtnewpt>, PredNewRel;
3270b57cec5SDimitry Andric  def PS_jmpretfnewpt : T_JMPr_c<1, 1, 1, J2_jumprfnewpt>, PredNewRel;
3280b57cec5SDimitry Andric}
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric//defm V6_vtran2x2_map : HexagonMapping<(outs HvxVR:$Vy32, HvxVR:$Vx32), (ins HvxVR:$Vx32in, IntRegs:$Rt32), "vtrans2x2(${Vy32},${Vx32},${Rt32})", (V6_vshuff HvxVR:$Vy32, HvxVR:$Vx32, HvxVR:$Vx32in, IntRegs:$Rt32)>;
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric// The reason for the custom inserter is to record all ALLOCA instructions
3330b57cec5SDimitry Andric// in MachineFunctionInfo.
3340b57cec5SDimitry Andriclet Defs = [R29], hasSideEffects = 1 in
3350b57cec5SDimitry Andricdef PS_alloca: Pseudo <(outs IntRegs:$Rd),
3360b57cec5SDimitry Andric                       (ins IntRegs:$Rs, u32_0Imm:$A), "", []>;
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric// Load predicate.
3390b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
3400b57cec5SDimitry Andric    isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
3410b57cec5SDimitry Andricdef LDriw_pred : LDInst<(outs PredRegs:$dst),
3420b57cec5SDimitry Andric                        (ins IntRegs:$addr, s32_0Imm:$off),
3430b57cec5SDimitry Andric                        ".error \"should not emit\"", []>;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric// Load modifier.
3460b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
3470b57cec5SDimitry Andric    isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
3480b57cec5SDimitry Andricdef LDriw_ctr : LDInst<(outs CtrRegs:$dst),
3490b57cec5SDimitry Andric                        (ins IntRegs:$addr, s32_0Imm:$off),
3500b57cec5SDimitry Andric                        ".error \"should not emit\"", []>;
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1 in
3540b57cec5SDimitry Andricdef PS_pselect: InstHexagon<(outs DoubleRegs:$Rd),
3550b57cec5SDimitry Andric      (ins PredRegs:$Pu, DoubleRegs:$Rs, DoubleRegs:$Rt),
3560b57cec5SDimitry Andric      ".error \"should not emit\" ", [], "", A2_tfrpt.Itinerary, TypeALU32_2op>;
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andriclet isBranch = 1, isBarrier = 1, Defs = [PC], hasSideEffects = 0,
3590b57cec5SDimitry Andric    isPredicable = 1,
3600b57cec5SDimitry Andric    isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
3610b57cec5SDimitry Andric    opExtentBits = 24, opExtentAlign = 2, InputType = "imm" in
3620b57cec5SDimitry Andricclass T_JMP: InstHexagon<(outs), (ins b30_2Imm:$dst),
3630b57cec5SDimitry Andric      "jump $dst",
3640b57cec5SDimitry Andric      [], "", J2_jump.Itinerary, TypeJ>, OpcodeHexagon {
3650b57cec5SDimitry Andric    bits<24> dst;
3660b57cec5SDimitry Andric    let IClass = 0b0101;
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andric    let Inst{27-25} = 0b100;
3690b57cec5SDimitry Andric    let Inst{24-16} = dst{23-15};
3700b57cec5SDimitry Andric    let Inst{13-1} = dst{14-2};
3710b57cec5SDimitry Andric}
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric// Restore registers and dealloc return function call.
3740b57cec5SDimitry Andriclet isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3750b57cec5SDimitry Andric    Defs = [R29, R30, R31, PC], isPredicable = 0, isAsmParserOnly = 1 in {
3760b57cec5SDimitry Andric  def RESTORE_DEALLOC_RET_JMP_V4 : T_JMP;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric  let isExtended = 1, opExtendable = 0 in
3790b57cec5SDimitry Andric  def RESTORE_DEALLOC_RET_JMP_V4_EXT : T_JMP;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric  let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
3820b57cec5SDimitry Andric    def RESTORE_DEALLOC_RET_JMP_V4_PIC : T_JMP;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric    let isExtended = 1, opExtendable = 0 in
3850b57cec5SDimitry Andric    def RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC : T_JMP;
3860b57cec5SDimitry Andric  }
3870b57cec5SDimitry Andric}
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric// Restore registers and dealloc frame before a tail call.
3900b57cec5SDimitry Andriclet isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
3910b57cec5SDimitry Andric  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : T_Call<"">, PredRel;
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric  let isExtended = 1, opExtendable = 0 in
3940b57cec5SDimitry Andric  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT : T_Call<"">, PredRel;
3950b57cec5SDimitry Andric
3960b57cec5SDimitry Andric  let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
3970b57cec5SDimitry Andric    def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC : T_Call<"">, PredRel;
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric    let isExtended = 1, opExtendable = 0 in
4000b57cec5SDimitry Andric    def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC : T_Call<"">, PredRel;
4010b57cec5SDimitry Andric  }
4020b57cec5SDimitry Andric}
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric// Save registers function call.
4050b57cec5SDimitry Andriclet isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
4060b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4 : T_Call<"">, PredRel;
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric  let isExtended = 1, opExtendable = 0 in
4090b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4_EXT : T_Call<"">, PredRel;
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric  let Defs = [P0] in
4120b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4STK : T_Call<"">, PredRel;
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric  let Defs = [P0], isExtended = 1, opExtendable = 0 in
4150b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4STK_EXT : T_Call<"">, PredRel;
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric  let Defs = [R14, R15, R28] in
4180b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4_PIC : T_Call<"">, PredRel;
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric  let Defs = [R14, R15, R28], isExtended = 1, opExtendable = 0 in
4210b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4_EXT_PIC : T_Call<"">, PredRel;
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric  let Defs = [R14, R15, R28, P0] in
4240b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4STK_PIC : T_Call<"">, PredRel;
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric  let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in
4270b57cec5SDimitry Andric  def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<"">, PredRel;
4280b57cec5SDimitry Andric}
4290b57cec5SDimitry Andric
430*bdd1243dSDimitry Andriclet Predicates = [UseHVX], isPseudo = 1, isCodeGenOnly = 1,
431*bdd1243dSDimitry Andric                 hasSideEffects = 0, hasPostISelHook = 1 in
432*bdd1243dSDimitry Andricclass Vsplatr_template : InstHexagon<(outs HvxVR:$Vd), (ins IntRegs:$Rs),
433*bdd1243dSDimitry Andric                         "", [], "", V6_lvsplatw.Itinerary, V6_lvsplatw.Type>;
434*bdd1243dSDimitry Andricdef PS_vsplatrb: Vsplatr_template;
435*bdd1243dSDimitry Andricdef PS_vsplatrh: Vsplatr_template;
436*bdd1243dSDimitry Andricdef PS_vsplatrw: Vsplatr_template;
437*bdd1243dSDimitry Andric
438*bdd1243dSDimitry Andriclet Predicates = [UseHVX], isPseudo = 1, isCodeGenOnly = 1,
439*bdd1243dSDimitry Andric                 hasSideEffects = 0, hasPostISelHook = 1 in
440*bdd1243dSDimitry Andricclass Vsplati_template : InstHexagon<(outs HvxVR:$Vd), (ins s32_0Imm:$Val),
441*bdd1243dSDimitry Andric                         "", [], "", V6_lvsplatw.Itinerary, V6_lvsplatw.Type>;
442*bdd1243dSDimitry Andricdef PS_vsplatib: Vsplati_template;
443*bdd1243dSDimitry Andricdef PS_vsplatih: Vsplati_template;
444*bdd1243dSDimitry Andricdef PS_vsplatiw: Vsplati_template;
445*bdd1243dSDimitry Andric
4460b57cec5SDimitry Andric// Vector store pseudos
4470b57cec5SDimitry Andriclet Predicates = [HasV60,UseHVX], isPseudo = 1, isCodeGenOnly = 1,
4480b57cec5SDimitry Andric    mayStore = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
449480093f4SDimitry Andricclass STriv_template<RegisterClass RC, InstHexagon rootInst>
4500b57cec5SDimitry Andric  : InstHexagon<(outs), (ins IntRegs:$addr, s32_0Imm:$off, RC:$src),
4510b57cec5SDimitry Andric    "", [], "", rootInst.Itinerary, rootInst.Type>;
4520b57cec5SDimitry Andric
453480093f4SDimitry Andricdef PS_vstorerv_ai: STriv_template<HvxVR, V6_vS32b_ai>,
4540b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
455480093f4SDimitry Andricdef PS_vstorerv_nt_ai: STriv_template<HvxVR, V6_vS32b_nt_ai>,
4560b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
457480093f4SDimitry Andricdef PS_vstorerw_ai: STriv_template<HvxWR, V6_vS32b_ai>,
458480093f4SDimitry Andric      Requires<[HasV60,UseHVX]>;
459480093f4SDimitry Andricdef PS_vstorerw_nt_ai: STriv_template<HvxWR, V6_vS32b_nt_ai>,
4600b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andriclet isPseudo = 1, isCodeGenOnly = 1, mayStore = 1, hasSideEffects = 0 in
4630b57cec5SDimitry Andricdef PS_vstorerq_ai: Pseudo<(outs),
4640b57cec5SDimitry Andric      (ins IntRegs:$Rs, s32_0Imm:$Off, HvxQR:$Qt), "", []>,
4650b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andric// Vector load pseudos
4680b57cec5SDimitry Andriclet Predicates = [HasV60, UseHVX], isPseudo = 1, isCodeGenOnly = 1,
4690b57cec5SDimitry Andric    mayLoad = 1, accessSize = HVXVectorAccess, hasSideEffects = 0 in
470480093f4SDimitry Andricclass LDriv_template<RegisterClass RC, InstHexagon rootInst>
4710b57cec5SDimitry Andric  : InstHexagon<(outs RC:$dst), (ins IntRegs:$addr, s32_0Imm:$off),
4720b57cec5SDimitry Andric    "", [], "", rootInst.Itinerary, rootInst.Type>;
4730b57cec5SDimitry Andric
474480093f4SDimitry Andricdef PS_vloadrv_ai: LDriv_template<HvxVR, V6_vL32b_ai>,
4750b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
476480093f4SDimitry Andricdef PS_vloadrv_nt_ai: LDriv_template<HvxVR, V6_vL32b_nt_ai>,
4770b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
478480093f4SDimitry Andricdef PS_vloadrw_ai: LDriv_template<HvxWR, V6_vL32b_ai>,
479480093f4SDimitry Andric      Requires<[HasV60,UseHVX]>;
480480093f4SDimitry Andricdef PS_vloadrw_nt_ai: LDriv_template<HvxWR, V6_vL32b_nt_ai>,
4810b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andriclet isPseudo = 1, isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in
4840b57cec5SDimitry Andricdef PS_vloadrq_ai: Pseudo<(outs HvxQR:$Qd),
4850b57cec5SDimitry Andric      (ins IntRegs:$Rs, s32_0Imm:$Off), "", []>,
4860b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric
4890b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
4900b57cec5SDimitry Andricclass VSELInst<dag outs, dag ins, InstHexagon rootInst>
4910b57cec5SDimitry Andric  : InstHexagon<outs, ins, "", [], "", rootInst.Itinerary, rootInst.Type>;
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andricdef PS_vselect: VSELInst<(outs HvxVR:$dst),
4940b57cec5SDimitry Andric      (ins PredRegs:$src1, HvxVR:$src2, HvxVR:$src3), V6_vcmov>,
4950b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4960b57cec5SDimitry Andricdef PS_wselect: VSELInst<(outs HvxWR:$dst),
4970b57cec5SDimitry Andric      (ins PredRegs:$src1, HvxWR:$src2, HvxWR:$src3), V6_vccombine>,
4980b57cec5SDimitry Andric      Requires<[HasV60,UseHVX]>;
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andriclet hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1,
5010b57cec5SDimitry Andric    isCodeGenOnly = 1 in {
5020b57cec5SDimitry Andric  def PS_qtrue:  InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "",
5030b57cec5SDimitry Andric                 V6_veqw.Itinerary, TypeCVI_VA>;
5040b57cec5SDimitry Andric  def PS_qfalse: InstHexagon<(outs HvxQR:$Qd), (ins), "", [], "",
5050b57cec5SDimitry Andric                 V6_vgtw.Itinerary, TypeCVI_VA>;
5060b57cec5SDimitry Andric  def PS_vdd0:   InstHexagon<(outs HvxWR:$Vd), (ins), "", [], "",
5070b57cec5SDimitry Andric                 V6_vsubw_dv.Itinerary, TypeCVI_VA_DV>;
5080b57cec5SDimitry Andric}
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric// Store predicate.
5110b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
5120b57cec5SDimitry Andric    isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
5130b57cec5SDimitry Andricdef STriw_pred : STInst<(outs),
5140b57cec5SDimitry Andric      (ins IntRegs:$addr, s32_0Imm:$off, PredRegs:$src1),
5150b57cec5SDimitry Andric      ".error \"should not emit\"", []>;
5160b57cec5SDimitry Andric// Store modifier.
5170b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
5180b57cec5SDimitry Andric    isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
5190b57cec5SDimitry Andricdef STriw_ctr : STInst<(outs),
5200b57cec5SDimitry Andric      (ins IntRegs:$addr, s32_0Imm:$off, CtrRegs:$src1),
5210b57cec5SDimitry Andric      ".error \"should not emit\"", []>;
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andriclet isExtendable = 1, opExtendable = 1, opExtentBits = 6,
5240b57cec5SDimitry Andric    isAsmParserOnly = 1 in
5250b57cec5SDimitry Andricdef TFRI64_V4 : InstHexagon<(outs DoubleRegs:$dst),
5260b57cec5SDimitry Andric    (ins u64_0Imm:$src1),
5270b57cec5SDimitry Andric    "$dst = #$src1", [], "",
5280b57cec5SDimitry Andric    A2_combineii.Itinerary, TypeALU32_2op>, OpcodeHexagon;
5290b57cec5SDimitry Andric
5300b57cec5SDimitry Andric// Hexagon doesn't have a vector multiply with C semantics.
5315ffd83dbSDimitry Andric// Instead, generate a pseudo instruction that gets expanded into two
5320b57cec5SDimitry Andric// scalar MPYI instructions.
5330b57cec5SDimitry Andric// This is expanded by ExpandPostRAPseudos.
5340b57cec5SDimitry Andriclet isPseudo = 1 in
5350b57cec5SDimitry Andricdef PS_vmulw : PseudoM<(outs DoubleRegs:$Rd),
5360b57cec5SDimitry Andric      (ins DoubleRegs:$Rs, DoubleRegs:$Rt), "", []>;
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andriclet isPseudo = 1 in
5390b57cec5SDimitry Andricdef PS_vmulw_acc : PseudoM<(outs DoubleRegs:$Rd),
5400b57cec5SDimitry Andric      (ins DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt), "", [],
5410b57cec5SDimitry Andric      "$Rd = $Rx">;
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andricdef DuplexIClass0:  InstDuplex < 0 >;
5440b57cec5SDimitry Andricdef DuplexIClass1:  InstDuplex < 1 >;
5450b57cec5SDimitry Andricdef DuplexIClass2:  InstDuplex < 2 >;
5460b57cec5SDimitry Andriclet isExtendable = 1 in {
5470b57cec5SDimitry Andric  def DuplexIClass3:  InstDuplex < 3 >;
5480b57cec5SDimitry Andric  def DuplexIClass4:  InstDuplex < 4 >;
5490b57cec5SDimitry Andric  def DuplexIClass5:  InstDuplex < 5 >;
5500b57cec5SDimitry Andric  def DuplexIClass6:  InstDuplex < 6 >;
5510b57cec5SDimitry Andric  def DuplexIClass7:  InstDuplex < 7 >;
5520b57cec5SDimitry Andric}
5530b57cec5SDimitry Andricdef DuplexIClass8:  InstDuplex < 8 >;
5540b57cec5SDimitry Andricdef DuplexIClass9:  InstDuplex < 9 >;
5550b57cec5SDimitry Andricdef DuplexIClassA:  InstDuplex < 0xA >;
5560b57cec5SDimitry Andricdef DuplexIClassB:  InstDuplex < 0xB >;
5570b57cec5SDimitry Andricdef DuplexIClassC:  InstDuplex < 0xC >;
5580b57cec5SDimitry Andricdef DuplexIClassD:  InstDuplex < 0xD >;
5590b57cec5SDimitry Andricdef DuplexIClassE:  InstDuplex < 0xE >;
5600b57cec5SDimitry Andricdef DuplexIClassF:  InstDuplex < 0xF >;
5610b57cec5SDimitry Andric
5620b57cec5SDimitry Andric// Pseudos for circular buffer instructions. These are needed in order to
5630b57cec5SDimitry Andric// allocate the correct pair of CSx and Mx registers.
5640b57cec5SDimitry Andricmulticlass NewCircularLoad<RegisterClass RC, MemAccessSize MS> {
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
5670b57cec5SDimitry Andric    addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
5685ffd83dbSDimitry Andric  // Use timing class of L2_loadrb_pci.
5690b57cec5SDimitry Andric  def NAME#_pci : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
5700b57cec5SDimitry Andric       (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, IntRegs:$Cs),
5715ffd83dbSDimitry Andric       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_5ceb2f9e>;
5720b57cec5SDimitry Andric
5735ffd83dbSDimitry Andric  // Use timing class of L2_loadrb_pcr.
5740b57cec5SDimitry Andric  def NAME#_pcr : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
5750b57cec5SDimitry Andric       (ins IntRegs:$Rx32in, ModRegs:$Mu2, IntRegs:$Cs),
5765ffd83dbSDimitry Andric       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_075c8dd8>;
5770b57cec5SDimitry Andric}
5780b57cec5SDimitry Andric}
5790b57cec5SDimitry Andric
5800b57cec5SDimitry Andricdefm PS_loadrub : NewCircularLoad<IntRegs, ByteAccess>;
5810b57cec5SDimitry Andricdefm PS_loadrb : NewCircularLoad<IntRegs, ByteAccess>;
5820b57cec5SDimitry Andricdefm PS_loadruh : NewCircularLoad<IntRegs, HalfWordAccess>;
5830b57cec5SDimitry Andricdefm PS_loadrh : NewCircularLoad<IntRegs, HalfWordAccess>;
5840b57cec5SDimitry Andricdefm PS_loadri : NewCircularLoad<IntRegs, WordAccess>;
5850b57cec5SDimitry Andricdefm PS_loadrd : NewCircularLoad<DoubleRegs, DoubleWordAccess>;
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andricmulticlass NewCircularStore<RegisterClass RC, MemAccessSize MS> {
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
5900b57cec5SDimitry Andric    addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
5915ffd83dbSDimitry Andric  // Use timing class of S2_storerb_pci.
5920b57cec5SDimitry Andric  def NAME#_pci : STInst<(outs IntRegs:$Rx32),
5930b57cec5SDimitry Andric       (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, RC:$Rt32, IntRegs:$Cs),
5945ffd83dbSDimitry Andric       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_b4dc7630>;
5950b57cec5SDimitry Andric
5965ffd83dbSDimitry Andric  // Use timing class of S2_storerb_pcr.
5970b57cec5SDimitry Andric  def NAME#_pcr : STInst<(outs IntRegs:$Rx32),
5980b57cec5SDimitry Andric       (ins IntRegs:$Rx32in, ModRegs:$Mu2, RC:$Rt32, IntRegs:$Cs),
5995ffd83dbSDimitry Andric       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", tc_a2b365d2>;
6000b57cec5SDimitry Andric}
6010b57cec5SDimitry Andric}
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andricdefm PS_storerb : NewCircularStore<IntRegs, ByteAccess>;
6040b57cec5SDimitry Andricdefm PS_storerh : NewCircularStore<IntRegs, HalfWordAccess>;
6050b57cec5SDimitry Andricdefm PS_storerf : NewCircularStore<IntRegs, HalfWordAccess>;
6060b57cec5SDimitry Andricdefm PS_storeri : NewCircularStore<IntRegs, WordAccess>;
6070b57cec5SDimitry Andricdefm PS_storerd : NewCircularStore<DoubleRegs, WordAccess>;
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric// A pseudo that generates a runtime crash. This is used to implement
6100b57cec5SDimitry Andric// __builtin_trap.
6110b57cec5SDimitry Andriclet hasSideEffects = 1, isPseudo = 1, isCodeGenOnly = 1, isSolo = 1 in
6120b57cec5SDimitry Andricdef PS_crash: InstHexagon<(outs), (ins), "", [], "", PSEUDO, TypePSEUDO>;
6130eae32dcSDimitry Andric
6140eae32dcSDimitry Andric// This is actual trap1 instruction from before v65. It's here since it is
6150eae32dcSDimitry Andric// no longer included in DepInstrInfo.td.
6160eae32dcSDimitry Andricdef PS_trap1 : HInst<(outs), (ins u8_0Imm:$Ii), "trap1(#$Ii)", tc_53c851ab,
6170eae32dcSDimitry Andric                     TypeJ>, Enc_a51a9a, Requires<[HasPreV65]> {
6180eae32dcSDimitry Andric  let Inst{1-0} = 0b00;
6190eae32dcSDimitry Andric  let Inst{7-5} = 0b000;
6200eae32dcSDimitry Andric  let Inst{13-13} = 0b0;
6210eae32dcSDimitry Andric  let Inst{31-16} = 0b0101010010000000;
6220eae32dcSDimitry Andric}
6230eae32dcSDimitry Andric
624