diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index e14a2f27f17..aceb20169e8 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -1742,6 +1742,43 @@ let AddedComplexity = 20 in def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))), (i32 (L2_loadrub_io IntRegs:$src1, s11_0ImmPred:$offset))>; +//===----------------------------------------------------------------------===// +// Template class for post increment loads with register offset. +//===----------------------------------------------------------------------===// +let hasSideEffects = 0, addrMode = PostInc in +class T_load_pr MajOp, + MemAccessSize AccessSz> + : LDInstPI <(outs RC:$dst, IntRegs:$_dst_), + (ins IntRegs:$src1, ModRegs:$src2), + "$dst = "#mnemonic#"($src1++$src2)" , + [], "$src1 = $_dst_" > { + bits<5> dst; + bits<5> src1; + bits<1> src2; + + let accessSize = AccessSz; + let IClass = 0b1001; + + let Inst{27-25} = 0b110; + let Inst{24-21} = MajOp; + let Inst{20-16} = src1; + let Inst{13} = src2; + let Inst{12} = 0b0; + let Inst{7} = 0b0; + let Inst{4-0} = dst; + } + +let hasNewValue = 1, isCodeGenOnly = 0 in { + def L2_loadrb_pr : T_load_pr <"memb", IntRegs, 0b1000, ByteAccess>; + def L2_loadrub_pr : T_load_pr <"memub", IntRegs, 0b1001, ByteAccess>; + def L2_loadrh_pr : T_load_pr <"memh", IntRegs, 0b1010, HalfWordAccess>; + def L2_loadruh_pr : T_load_pr <"memuh", IntRegs, 0b1011, HalfWordAccess>; + def L2_loadri_pr : T_load_pr <"memw", IntRegs, 0b1100, WordAccess>; +} + +let isCodeGenOnly = 0 in +def L2_loadrd_pr : T_load_pr <"memd", DoubleRegs, 0b1110, DoubleWordAccess>; + // Load predicate. let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13, isPseudo = 1, Defs = [R10,R11,D5], hasSideEffects = 0 in @@ -1870,6 +1907,45 @@ let hasNewValue = 1, accessSize = WordAccess, opNewValue = 0, isCodeGenOnly = 0 def L2_loadw_locked : T_load_locked <"memw_locked", IntRegs>; let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in def L4_loadd_locked : T_load_locked <"memd_locked", DoubleRegs>; +//===----------------------------------------------------------------------===// +// Bit-reversed loads with auto-increment register +//===----------------------------------------------------------------------===// +let hasSideEffects = 0 in +class T_load_pbr majOp> + : LDInst + <(outs RC:$dst, IntRegs:$_dst_), + (ins IntRegs:$Rz, ModRegs:$Mu), + "$dst = "#mnemonic#"($Rz ++ $Mu:brev)" , + [] , "$Rz = $_dst_" > { + + let accessSize = addrSize; + + bits<5> dst; + bits<5> Rz; + bits<1> Mu; + + let IClass = 0b1001; + + let Inst{27-25} = 0b111; + let Inst{24-21} = majOp; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12} = 0b0; + let Inst{7} = 0b0; + let Inst{4-0} = dst; + } + +let hasNewValue =1, opNewValue = 0, isCodeGenOnly = 0 in { + def L2_loadrb_pbr : T_load_pbr <"memb", IntRegs, ByteAccess, 0b1000>; + def L2_loadrub_pbr : T_load_pbr <"memub", IntRegs, ByteAccess, 0b1001>; + def L2_loadrh_pbr : T_load_pbr <"memh", IntRegs, HalfWordAccess, 0b1010>; + def L2_loadruh_pbr : T_load_pbr <"memuh", IntRegs, HalfWordAccess, 0b1011>; + def L2_loadri_pbr : T_load_pbr <"memw", IntRegs, WordAccess, 0b1100>; +} + +let isCodeGenOnly = 0 in +def L2_loadrd_pbr : T_load_pbr <"memd", DoubleRegs, DoubleWordAccess, 0b1110>; //===----------------------------------------------------------------------===// // LD - diff --git a/test/MC/Disassembler/Hexagon/ld.txt b/test/MC/Disassembler/Hexagon/ld.txt index e4fb21fa7fe..041dcf82353 100644 --- a/test/MC/Disassembler/Hexagon/ld.txt +++ b/test/MC/Disassembler/Hexagon/ld.txt @@ -8,6 +8,10 @@ # CHECK: r17:16 = memd(r21 ++ I:circ(m1)) 0xb0 0xc0 0xd5 0x9b # CHECK: r17:16 = memd(r21++#40) +0x10 0xe0 0xd5 0x9d +# CHECK: r17:16 = memd(r21++m1) +0x10 0xe0 0xd5 0x9f +# CHECK: r17:16 = memd(r21 ++ m1:brev) 0x03 0x40 0x45 0x85 0x70 0xd8 0xd5 0x43 # CHECK: p3 = r5 # CHECK-NEXT: if (p3.new) r17:16 = memd(r21 + #24) @@ -35,6 +39,10 @@ # CHECK: r17 = memb(r21 ++ I:circ(m1)) 0xb1 0xc0 0x15 0x9b # CHECK: r17 = memb(r21++#5) +0x11 0xe0 0x15 0x9d +# CHECK: r17 = memb(r21++m1) +0x11 0xe0 0x15 0x9f +# CHECK: r17 = memb(r21 ++ m1:brev) 0x91 0xdd 0x15 0x41 # CHECK: if (p3) r17 = memb(r21 + #44) 0x03 0x40 0x45 0x85 0x91 0xdd 0x15 0x43 @@ -64,6 +72,10 @@ # CHECK: r17 = memh(r21 ++ I:circ(m1)) 0xb1 0xc0 0x55 0x9b # CHECK: r17 = memh(r21++#10) +0x11 0xe0 0x55 0x9d +# CHECK: r17 = memh(r21++m1) +0x11 0xe0 0x55 0x9f +# CHECK: r17 = memh(r21 ++ m1:brev) 0xb1 0xe6 0x55 0x9b # CHECK: if (p3) r17 = memh(r21++#10) 0xb1 0xee 0x55 0x9b @@ -83,6 +95,10 @@ # CHECK: r17 = memub(r21 ++ I:circ(m1)) 0xb1 0xc0 0x35 0x9b # CHECK: r17 = memub(r21++#5) +0x11 0xe0 0x35 0x9d +# CHECK: r17 = memub(r21++m1) +0x11 0xe0 0x35 0x9f +# CHECK: r17 = memub(r21 ++ m1:brev) 0xf1 0xdb 0x35 0x41 # CHECK: if (p3) r17 = memub(r21 + #31) 0x03 0x40 0x45 0x85 0xf1 0xdb 0x35 0x43 @@ -112,6 +128,10 @@ # CHECK: r17 = memuh(r21 ++ I:circ(m1)) 0xb1 0xc0 0x75 0x9b # CHECK: r17 = memuh(r21++#10) +0x11 0xe0 0x75 0x9d +# CHECK: r17 = memuh(r21++m1) +0x11 0xe0 0x75 0x9f +# CHECK: r17 = memuh(r21 ++ m1:brev) 0xb1 0xda 0x75 0x41 # CHECK: if (p3) r17 = memuh(r21 + #42) 0xb1 0xda 0x75 0x45 @@ -141,6 +161,10 @@ # CHECK: r17 = memw(r21 ++ I:circ(m1)) 0xb1 0xc0 0x95 0x9b # CHECK: r17 = memw(r21++#20) +0x11 0xe0 0x95 0x9d +# CHECK: r17 = memw(r21++m1) +0x11 0xe0 0x95 0x9f +# CHECK: r17 = memw(r21 ++ m1:brev) 0xb1 0xda 0x95 0x41 # CHECK: if (p3) r17 = memw(r21 + #84) 0xb1 0xda 0x95 0x45