diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index a2536464e59..3c7abfc8e2f 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -3009,6 +3009,40 @@ def S2_storerd_pci : T_store_pci<"memd", DoubleRegs, s4_3Imm, 0b1110, DoubleWordAccess>; } +let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 4 in +class T_storenew_pci MajOp, MemAccessSize AlignSize> + : NVInst < (outs IntRegs:$_dst_), + (ins IntRegs:$Rz, Imm:$offset, ModRegs:$Mu, IntRegs:$Nt), + #mnemonic#"($Rz ++ #$offset:circ($Mu)) = $Nt.new", + [], + "$Rz = $_dst_"> { + bits<5> Rz; + bits<6> offset; + bits<1> Mu; + bits<3> Nt; + + let accessSize = AlignSize; + + let IClass = 0b1010; + let Inst{27-21} = 0b1001101; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12-11} = MajOp; + let Inst{10-8} = Nt; + let Inst{7} = 0b0; + let Inst{6-3} = + !if (!eq(!cast(AlignSize), "WordAccess"), offset{5-2}, + !if (!eq(!cast(AlignSize), "HalfWordAccess"), offset{4-1}, + /* ByteAccess */ offset{3-0})); + let Inst{1} = 0b0; + } +let isCodeGenOnly = 0 in { +def S2_storerbnew_pci : T_storenew_pci <"memb", s4_0Imm, 0b00, ByteAccess>; +def S2_storerhnew_pci : T_storenew_pci <"memh", s4_1Imm, 0b01, HalfWordAccess>; +def S2_storerinew_pci : T_storenew_pci <"memw", s4_2Imm, 0b10, WordAccess>; +} + //===----------------------------------------------------------------------===// // Circular stores with auto-increment register //===----------------------------------------------------------------------===// @@ -3045,6 +3079,39 @@ def S2_storerf_pcr : T_store_pcr<"memh", IntRegs, 0b1011, HalfWordAccess, "Rt.h">; } +//===----------------------------------------------------------------------===// +// Circular .new stores with auto-increment register +//===----------------------------------------------------------------------===// +let Uses = [CS], isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3 in +class T_storenew_pcr MajOp, + MemAccessSize AlignSize> + : NVInst <(outs IntRegs:$_dst_), + (ins IntRegs:$Rz, ModRegs:$Mu, IntRegs:$Nt), + #mnemonic#"($Rz ++ I:circ($Mu)) = $Nt.new" , + [] , + "$Rz = $_dst_"> { + bits<5> Rz; + bits<1> Mu; + bits<3> Nt; + + let accessSize = AlignSize; + + let IClass = 0b1010; + let Inst{27-21} = 0b1001101; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12-11} = MajOp; + let Inst{10-8} = Nt; + let Inst{7} = 0b0; + let Inst{1} = 0b1; + } + +let isCodeGenOnly = 0 in { +def S2_storerbnew_pcr : T_storenew_pcr <"memb", 0b00, ByteAccess>; +def S2_storerhnew_pcr : T_storenew_pcr <"memh", 0b01, HalfWordAccess>; +def S2_storerinew_pcr : T_storenew_pcr <"memw", 0b10, WordAccess>; +} + //===----------------------------------------------------------------------===// // Bit-reversed stores with auto-increment register //===----------------------------------------------------------------------===// @@ -3090,6 +3157,40 @@ def S2_storerf_pbr : T_store_pbr<"memh", IntRegs, HalfWordAccess, 0b011, 1>; def S2_storerd_pbr : T_store_pbr<"memd", DoubleRegs, DoubleWordAccess, 0b110>; } +//===----------------------------------------------------------------------===// +// Bit-reversed .new stores with auto-increment register +//===----------------------------------------------------------------------===// +let isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3, + hasSideEffects = 0 in +class T_storenew_pbr majOp> + : NVInst <(outs IntRegs:$_dst_), + (ins IntRegs:$Rz, ModRegs:$Mu, IntRegs:$Nt), + #mnemonic#"($Rz ++ $Mu:brev) = $Nt.new", [], + "$Rz = $_dst_">, NewValueRel { + let accessSize = addrSize; + bits<5> Rz; + bits<1> Mu; + bits<3> Nt; + + let IClass = 0b1010; + + let Inst{27-21} = 0b1111101; + let Inst{12-11} = majOp; + let Inst{7} = 0b0; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{10-8} = Nt; + } + +let BaseOpcode = "S2_storerb_pbr", isCodeGenOnly = 0 in +def S2_storerbnew_pbr : T_storenew_pbr<"memb", ByteAccess, 0b00>; + +let BaseOpcode = "S2_storerh_pbr", isCodeGenOnly = 0 in +def S2_storerhnew_pbr : T_storenew_pbr<"memh", HalfWordAccess, 0b01>; + +let BaseOpcode = "S2_storeri_pbr", isCodeGenOnly = 0 in +def S2_storerinew_pbr : T_storenew_pbr<"memw", WordAccess, 0b10>; + //===----------------------------------------------------------------------===// // ST - //===----------------------------------------------------------------------===// @@ -3157,6 +3258,9 @@ let Defs = [USR_OVF], isCodeGenOnly = 0 in { } let Itinerary = S_2op_tc_2_SLOT23, isCodeGenOnly = 0 in { + // Bit reverse + def S2_brev : T_S2op_1_ii <"brev", 0b01, 0b110>; + // Absolute value word def A2_abs : T_S2op_1_ii <"abs", 0b10, 0b100>; diff --git a/test/MC/Disassembler/Hexagon/nv_st.txt b/test/MC/Disassembler/Hexagon/nv_st.txt index 83057098734..811a0ca0ff6 100644 --- a/test/MC/Disassembler/Hexagon/nv_st.txt +++ b/test/MC/Disassembler/Hexagon/nv_st.txt @@ -6,12 +6,21 @@ 0x1f 0x40 0x7f 0x70 0x15 0xc2 0xb1 0xa1 # CHECK: r31 = r31 # CHECK-NEXT: memb(r17+#21) = r2.new +0x1f 0x40 0x7f 0x70 0x02 0xe2 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memb(r17 ++ I:circ(m1)) = r2.new +0x1f 0x40 0x7f 0x70 0x28 0xe2 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memb(r17 ++ #5:circ(m1)) = r2.new 0x1f 0x40 0x7f 0x70 0x28 0xc2 0xb1 0xab # CHECK: r31 = r31 # CHECK-NEXT: memb(r17++#5) = r2.new 0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xad # CHECK: r31 = r31 # CHECK-NEXT: memb(r17++m1) = r2.new +0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xaf +# CHECK: r31 = r31 +# CHECK-NEXT: memb(r17 ++ m1:brev) = r2.new 0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x34 # CHECK: r31 = r31 # CHECK-NEXT: if (p3) memb(r17+r21<<#3) = r2.new @@ -61,12 +70,21 @@ 0x1f 0x40 0x7f 0x70 0x15 0xca 0xb1 0xa1 # CHECK: r31 = r31 # CHECK-NEXT: memh(r17+#42) = r2.new +0x1f 0x40 0x7f 0x70 0x02 0xea 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memh(r17 ++ I:circ(m1)) = r2.new +0x1f 0x40 0x7f 0x70 0x28 0xea 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memh(r17 ++ #10:circ(m1)) = r2.new 0x1f 0x40 0x7f 0x70 0x28 0xca 0xb1 0xab # CHECK: r31 = r31 # CHECK-NEXT: memh(r17++#10) = r2.new 0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xad # CHECK: r31 = r31 # CHECK-NEXT: memh(r17++m1) = r2.new +0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xaf +# CHECK: r31 = r31 +# CHECK-NEXT: memh(r17 ++ m1:brev) = r2.new 0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x34 # CHECK: r31 = r31 # CHECK-NEXT: if (p3) memh(r17+r21<<#3) = r2.new @@ -116,12 +134,21 @@ 0x1f 0x40 0x7f 0x70 0x15 0xd2 0xb1 0xa1 # CHECK: r31 = r31 # CHECK-NEXT: memw(r17+#84) = r2.new +0x1f 0x40 0x7f 0x70 0x28 0xf2 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memw(r17 ++ #20:circ(m1)) = r2.new +0x1f 0x40 0x7f 0x70 0x02 0xf2 0xb1 0xa9 +# CHECK: r31 = r31 +# CHECK-NEXT: memw(r17 ++ I:circ(m1)) = r2.new 0x1f 0x40 0x7f 0x70 0x28 0xd2 0xb1 0xab # CHECK: r31 = r31 # CHECK-NEXT: memw(r17++#20) = r2.new 0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xad # CHECK: r31 = r31 # CHECK-NEXT: memw(r17++m1) = r2.new +0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xaf +# CHECK: r31 = r31 +# CHECK-NEXT: memw(r17 ++ m1:brev) = r2.new 0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x34 # CHECK: r31 = r31 # CHECK-NEXT: if (p3) memw(r17+r21<<#3) = r2.new diff --git a/test/MC/Disassembler/Hexagon/xtype_bit.txt b/test/MC/Disassembler/Hexagon/xtype_bit.txt index d1ec38e0218..1b8e5c51540 100644 --- a/test/MC/Disassembler/Hexagon/xtype_bit.txt +++ b/test/MC/Disassembler/Hexagon/xtype_bit.txt @@ -66,6 +66,8 @@ # CHECK: r17 = parity(r21, r31) 0xd0 0xc0 0xd4 0x80 # CHECK: r17:16 = brev(r21:20) +0xd1 0xc0 0x55 0x8c +# CHECK: r17 = brev(r21) 0x11 0xdf 0xd5 0x8c # CHECK: r17 = setbit(r21, #31) 0x31 0xdf 0xd5 0x8c