From 507dd3270367eb3c2381c7f426a0a50d58df3a8d Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Tue, 6 Jan 2015 20:03:31 +0000 Subject: [PATCH] [Hexagon] Adding compound jump encodings. llvm-svn: 225291 --- llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td | 5 + llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td | 261 +++++++++++++++++++++++ llvm/test/MC/Disassembler/Hexagon/j.txt | 148 +++++++++++++ 3 files changed, 414 insertions(+) diff --git a/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td index d92f97b..5fec80b 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrFormatsV4.td @@ -19,6 +19,7 @@ def TypeMEMOP : IType<9>; def TypeNV : IType<10>; +def TypeCOMPOUND : IType<12>; def TypePREFIX : IType<30>; //----------------------------------------------------------------------------// @@ -65,3 +66,7 @@ let isCodeGenOnly = 1 in class EXTENDERInst pattern = []> : InstHexagon; + +class CJInst pattern = [], + string cstr = ""> + : InstHexagon; diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index 60b5e22..08bfd67 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -4212,3 +4212,264 @@ def Y2_dcfetchbo : LD0Inst<(outs), (ins IntRegs:$Rs, u11_3Imm:$u11_3), let Inst{13} = 0b0; let Inst{10-0} = u11_3{13-3}; } + +//===----------------------------------------------------------------------===// +// Compound instructions +//===----------------------------------------------------------------------===// + +let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, + isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, + opExtentBits = 11, opExtentAlign = 2, opExtendable = 1, + isTerminator = 1, validSubTargets = HasV4SubT in +class CJInst_tstbit_R0 + : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2), + ""#px#" = tstbit($Rs, #0); if (" + #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", + [], "", COMPOUND, TypeCOMPOUND> { + bits<4> Rs; + bits<11> r9_2; + + // np: !p[01] + let isPredicatedFalse = np; + // tnt: Taken/Not Taken + let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); + let isTaken = !if (!eq(tnt, "t"), 1, 0); + + let IClass = 0b0001; + let Inst{27-26} = 0b00; + let Inst{25} = !if (!eq(px, "!p1"), 1, + !if (!eq(px, "p1"), 1, 0)); + let Inst{24-23} = 0b11; + let Inst{22} = np; + let Inst{21-20} = r9_2{10-9}; + let Inst{19-16} = Rs; + let Inst{13} = !if (!eq(tnt, "t"), 1, 0); + let Inst{9-8} = 0b11; + let Inst{7-1} = r9_2{8-2}; +} + +let Defs = [PC, P0], Uses = [P0], isCodeGenOnly = 0 in { + def J4_tstbit0_tp0_jump_nt : CJInst_tstbit_R0<"p0", 0, "nt">; + def J4_tstbit0_tp0_jump_t : CJInst_tstbit_R0<"p0", 0, "t">; + def J4_tstbit0_fp0_jump_nt : CJInst_tstbit_R0<"p0", 1, "nt">; + def J4_tstbit0_fp0_jump_t : CJInst_tstbit_R0<"p0", 1, "t">; +} + +let Defs = [PC, P1], Uses = [P1], isCodeGenOnly = 0 in { + def J4_tstbit0_tp1_jump_nt : CJInst_tstbit_R0<"p1", 0, "nt">; + def J4_tstbit0_tp1_jump_t : CJInst_tstbit_R0<"p1", 0, "t">; + def J4_tstbit0_fp1_jump_nt : CJInst_tstbit_R0<"p1", 1, "nt">; + def J4_tstbit0_fp1_jump_t : CJInst_tstbit_R0<"p1", 1, "t">; +} + + +let isBranch = 1, hasSideEffects = 0, + isExtentSigned = 1, isPredicated = 1, isPredicatedNew = 1, + isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, + opExtendable = 2, isTerminator = 1, validSubTargets = HasV4SubT in +class CJInst_RR + : InstHexagon<(outs), (ins IntRegs:$Rs, IntRegs:$Rt, brtarget:$r9_2), + ""#px#" = cmp."#op#"($Rs, $Rt); if (" + #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", + [], "", COMPOUND, TypeCOMPOUND> { + bits<4> Rs; + bits<4> Rt; + bits<11> r9_2; + + // np: !p[01] + let isPredicatedFalse = np; + // tnt: Taken/Not Taken + let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); + let isTaken = !if (!eq(tnt, "t"), 1, 0); + + let IClass = 0b0001; + let Inst{27-23} = !if (!eq(op, "eq"), 0b01000, + !if (!eq(op, "gt"), 0b01001, + !if (!eq(op, "gtu"), 0b01010, 0))); + let Inst{22} = np; + let Inst{21-20} = r9_2{10-9}; + let Inst{19-16} = Rs; + let Inst{13} = !if (!eq(tnt, "t"), 1, 0); + // px: Predicate reg 0/1 + let Inst{12} = !if (!eq(px, "!p1"), 1, + !if (!eq(px, "p1"), 1, 0)); + let Inst{11-8} = Rt; + let Inst{7-1} = r9_2{8-2}; +} + +// P[10] taken/not taken. +multiclass T_tnt_CJInst_RR { + let Defs = [PC, P0], Uses = [P0] in { + def NAME#p0_jump_nt : CJInst_RR<"p0", op, np, "nt">; + def NAME#p0_jump_t : CJInst_RR<"p0", op, np, "t">; + } + let Defs = [PC, P1], Uses = [P1] in { + def NAME#p1_jump_nt : CJInst_RR<"p1", op, np, "nt">; + def NAME#p1_jump_t : CJInst_RR<"p1", op, np, "t">; + } +} +// Predicate / !Predicate +multiclass T_pnp_CJInst_RR{ + defm J4_cmp#NAME#_t : T_tnt_CJInst_RR; + defm J4_cmp#NAME#_f : T_tnt_CJInst_RR; +} +// TypeCJ Instructions compare RR and jump +let isCodeGenOnly = 0 in { +defm eq : T_pnp_CJInst_RR<"eq">; +defm gt : T_pnp_CJInst_RR<"gt">; +defm gtu : T_pnp_CJInst_RR<"gtu">; +} + +let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, + isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, opExtentBits = 11, + opExtentAlign = 2, opExtendable = 2, isTerminator = 1, + validSubTargets = HasV4SubT in +class CJInst_RU5 + : InstHexagon<(outs), (ins IntRegs:$Rs, u5Imm:$U5, brtarget:$r9_2), + ""#px#" = cmp."#op#"($Rs, #$U5); if (" + #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", + [], "", COMPOUND, TypeCOMPOUND> { + bits<4> Rs; + bits<5> U5; + bits<11> r9_2; + + // np: !p[01] + let isPredicatedFalse = np; + // tnt: Taken/Not Taken + let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); + let isTaken = !if (!eq(tnt, "t"), 1, 0); + + let IClass = 0b0001; + let Inst{27-26} = 0b00; + // px: Predicate reg 0/1 + let Inst{25} = !if (!eq(px, "!p1"), 1, + !if (!eq(px, "p1"), 1, 0)); + let Inst{24-23} = !if (!eq(op, "eq"), 0b00, + !if (!eq(op, "gt"), 0b01, + !if (!eq(op, "gtu"), 0b10, 0))); + let Inst{22} = np; + let Inst{21-20} = r9_2{10-9}; + let Inst{19-16} = Rs; + let Inst{13} = !if (!eq(tnt, "t"), 1, 0); + let Inst{12-8} = U5; + let Inst{7-1} = r9_2{8-2}; +} +// P[10] taken/not taken. +multiclass T_tnt_CJInst_RU5 { + let Defs = [PC, P0], Uses = [P0] in { + def NAME#p0_jump_nt : CJInst_RU5<"p0", op, np, "nt">; + def NAME#p0_jump_t : CJInst_RU5<"p0", op, np, "t">; + } + let Defs = [PC, P1], Uses = [P1] in { + def NAME#p1_jump_nt : CJInst_RU5<"p1", op, np, "nt">; + def NAME#p1_jump_t : CJInst_RU5<"p1", op, np, "t">; + } +} +// Predicate / !Predicate +multiclass T_pnp_CJInst_RU5{ + defm J4_cmp#NAME#i_t : T_tnt_CJInst_RU5; + defm J4_cmp#NAME#i_f : T_tnt_CJInst_RU5; +} +// TypeCJ Instructions compare RI and jump +let isCodeGenOnly = 0 in { +defm eq : T_pnp_CJInst_RU5<"eq">; +defm gt : T_pnp_CJInst_RU5<"gt">; +defm gtu : T_pnp_CJInst_RU5<"gtu">; +} + +let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, + isPredicated = 1, isPredicatedFalse = 1, isPredicatedNew = 1, + isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, opExtendable = 1, + isTerminator = 1, validSubTargets = HasV4SubT in +class CJInst_Rn1 + : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2), + ""#px#" = cmp."#op#"($Rs,#-1); if (" + #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", + [], "", COMPOUND, TypeCOMPOUND> { + bits<4> Rs; + bits<11> r9_2; + + // np: !p[01] + let isPredicatedFalse = np; + // tnt: Taken/Not Taken + let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); + let isTaken = !if (!eq(tnt, "t"), 1, 0); + + let IClass = 0b0001; + let Inst{27-26} = 0b00; + let Inst{25} = !if (!eq(px, "!p1"), 1, + !if (!eq(px, "p1"), 1, 0)); + + let Inst{24-23} = 0b11; + let Inst{22} = np; + let Inst{21-20} = r9_2{10-9}; + let Inst{19-16} = Rs; + let Inst{13} = !if (!eq(tnt, "t"), 1, 0); + let Inst{9-8} = !if (!eq(op, "eq"), 0b00, + !if (!eq(op, "gt"), 0b01, 0)); + let Inst{7-1} = r9_2{8-2}; +} + +// P[10] taken/not taken. +multiclass T_tnt_CJInst_Rn1 { + let Defs = [PC, P0], Uses = [P0] in { + def NAME#p0_jump_nt : CJInst_Rn1<"p0", op, np, "nt">; + def NAME#p0_jump_t : CJInst_Rn1<"p0", op, np, "t">; + } + let Defs = [PC, P1], Uses = [P1] in { + def NAME#p1_jump_nt : CJInst_Rn1<"p1", op, np, "nt">; + def NAME#p1_jump_t : CJInst_Rn1<"p1", op, np, "t">; + } +} +// Predicate / !Predicate +multiclass T_pnp_CJInst_Rn1{ + defm J4_cmp#NAME#n1_t : T_tnt_CJInst_Rn1; + defm J4_cmp#NAME#n1_f : T_tnt_CJInst_Rn1; +} +// TypeCJ Instructions compare -1 and jump +let isCodeGenOnly = 0 in { +defm eq : T_pnp_CJInst_Rn1<"eq">; +defm gt : T_pnp_CJInst_Rn1<"gt">; +} + +// J4_jumpseti: Direct unconditional jump and set register to immediate. +let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1, + isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11, + opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT, + isCodeGenOnly = 0 in +def J4_jumpseti: CJInst < + (outs IntRegs:$Rd), + (ins u6Imm:$U6, brtarget:$r9_2), + "$Rd = #$U6 ; jump $r9_2"> { + bits<4> Rd; + bits<6> U6; + bits<11> r9_2; + + let IClass = 0b0001; + let Inst{27-24} = 0b0110; + let Inst{21-20} = r9_2{10-9}; + let Inst{19-16} = Rd; + let Inst{13-8} = U6; + let Inst{7-1} = r9_2{8-2}; + } + +// J4_jumpsetr: Direct unconditional jump and transfer register. +let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1, + isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11, + opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT, + isCodeGenOnly = 0 in +def J4_jumpsetr: CJInst < + (outs IntRegs:$Rd), + (ins IntRegs:$Rs, brtarget:$r9_2), + "$Rd = $Rs ; jump $r9_2"> { + bits<4> Rd; + bits<4> Rs; + bits<11> r9_2; + + let IClass = 0b0001; + let Inst{27-24} = 0b0111; + let Inst{21-20} = r9_2{10-9}; + let Inst{11-8} = Rd; + let Inst{19-16} = Rs; + let Inst{7-1} = r9_2{8-2}; + } diff --git a/llvm/test/MC/Disassembler/Hexagon/j.txt b/llvm/test/MC/Disassembler/Hexagon/j.txt index 2edbbda..c14d034 100644 --- a/llvm/test/MC/Disassembler/Hexagon/j.txt +++ b/llvm/test/MC/Disassembler/Hexagon/j.txt @@ -6,3 +6,151 @@ # CHECK: if (p3) call 0x22 0xc3 0x20 0x5d # CHECK: if (!p3) call +0x00 0xc0 0x89 0x11 +# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:nt +0x00 0xc1 0x89 0x11 +# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:nt +0x00 0xc3 0x89 0x11 +# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:nt +0x00 0xe0 0x89 0x11 +# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:t +0x00 0xe1 0x89 0x11 +# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:t +0x00 0xe3 0x89 0x11 +# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:t +0x00 0xc0 0xc9 0x11 +# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:nt +0x00 0xc1 0xc9 0x11 +# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:nt +0x00 0xc3 0xc9 0x11 +# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:nt +0x00 0xe0 0xc9 0x11 +# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:t +0x00 0xe1 0xc9 0x11 +# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:t +0x00 0xe3 0xc9 0x11 +# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:t +0x00 0xd5 0x09 0x10 +# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:nt +0x00 0xf5 0x09 0x10 +# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:t +0x00 0xd5 0x49 0x10 +# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:nt +0x00 0xf5 0x49 0x10 +# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:t +0x00 0xd5 0x89 0x10 +# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:nt +0x00 0xf5 0x89 0x10 +# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:t +0x00 0xd5 0xc9 0x10 +# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:nt +0x00 0xf5 0xc9 0x10 +# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:t +0x00 0xd5 0x09 0x11 +# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:nt +0x00 0xf5 0x09 0x11 +# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:t +0x00 0xd5 0x49 0x11 +# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:nt +0x00 0xf5 0x49 0x11 +# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:t +0x00 0xc0 0x89 0x13 +# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:nt +0x00 0xc1 0x89 0x13 +# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:nt +0x00 0xc3 0x89 0x13 +# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:nt +0x00 0xe0 0x89 0x13 +# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:t +0x00 0xe1 0x89 0x13 +# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:t +0x00 0xe3 0x89 0x13 +# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:t +0x00 0xc0 0xc9 0x13 +# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:nt +0x00 0xc1 0xc9 0x13 +# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:nt +0x00 0xc3 0xc9 0x13 +# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:nt +0x00 0xe0 0xc9 0x13 +# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:t +0x00 0xe1 0xc9 0x13 +# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:t +0x00 0xe3 0xc9 0x13 +# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:t +0x00 0xd5 0x09 0x12 +# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:nt +0x00 0xf5 0x09 0x12 +# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:t +0x00 0xd5 0x49 0x12 +# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:nt +0x00 0xf5 0x49 0x12 +# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:t +0x00 0xd5 0x89 0x12 +# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:nt +0x00 0xf5 0x89 0x12 +# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:t +0x00 0xd5 0xc9 0x12 +# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:nt +0x00 0xf5 0xc9 0x12 +# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:t +0x00 0xd5 0x09 0x13 +# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:nt +0x00 0xf5 0x09 0x13 +# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:t +0x00 0xd5 0x49 0x13 +# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:nt +0x00 0xf5 0x49 0x13 +# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:t +0x00 0xcd 0x09 0x14 +# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:nt +0x00 0xdd 0x09 0x14 +# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:nt +0x00 0xed 0x09 0x14 +# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:t +0x00 0xfd 0x09 0x14 +# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:t +0x00 0xcd 0x49 0x14 +# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:nt +0x00 0xdd 0x49 0x14 +# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:nt +0x00 0xed 0x49 0x14 +# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:t +0x00 0xfd 0x49 0x14 +# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:t +0x00 0xcd 0x89 0x14 +# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:nt +0x00 0xdd 0x89 0x14 +# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:nt +0x00 0xed 0x89 0x14 +# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:t +0x00 0xfd 0x89 0x14 +# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:t +0x00 0xcd 0xc9 0x14 +# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:nt +0x00 0xdd 0xc9 0x14 +# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:nt +0x00 0xed 0xc9 0x14 +# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:t +0x00 0xfd 0xc9 0x14 +# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:t +0x00 0xcd 0x09 0x15 +# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:nt +0x00 0xdd 0x09 0x15 +# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:nt +0x00 0xed 0x09 0x15 +# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:t +0x00 0xfd 0x09 0x15 +# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:t +0x00 0xcd 0x49 0x15 +# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:nt +0x00 0xdd 0x49 0x15 +# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:nt +0x00 0xed 0x49 0x15 +# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:t +0x00 0xfd 0x49 0x15 +# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:t +0x00 0xd5 0x09 0x16 +# CHECK: r9 = #21 ; jump +0x00 0xc9 0x0d 0x17 +# CHECK: r9 = r13 ; jump -- 2.7.4