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