From 025f860638d20ed3c9774934f301647643ac8dc8 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Mon, 8 Dec 2014 21:19:18 +0000 Subject: [PATCH] [Hexagon] Adding xtype parity, min, minu, max, maxu instructions. llvm-svn: 223693 --- .../Target/Hexagon/HexagonISelLowering.cpp | 14 +++ llvm/lib/Target/Hexagon/HexagonISelLowering.h | 4 + llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 87 +++++++++++++++++++ .../lib/Target/Hexagon/HexagonRegisterInfo.td | 5 ++ .../MC/Disassembler/Hexagon/xtype_alu.txt | 8 ++ .../MC/Disassembler/Hexagon/xtype_bit.txt | 4 + 6 files changed, 122 insertions(+) create mode 100644 llvm/test/MC/Disassembler/Hexagon/xtype_bit.txt diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 764608857b82..d86cccdf2e10 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1705,3 +1705,17 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization( // information is not available. return true; } + +// Return true when the given node fits in a positive half word. +bool llvm::isPositiveHalfWord(SDNode *N) { + ConstantSDNode *CN = dyn_cast(N); + if (CN && CN->getSExtValue() > 0 && isInt<16>(CN->getSExtValue())) + return true; + + switch (N->getOpcode()) { + default: + return false; + case ISD::SIGN_EXTEND_INREG: + return true; + } +} diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 99ac0eebd180..680c228e6a7f 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -21,6 +21,10 @@ #include "llvm/Target/TargetLowering.h" namespace llvm { + +// Return true when the given node fits in a positive half word. +bool isPositiveHalfWord(SDNode *N); + namespace HexagonISD { enum { FIRST_NUMBER = ISD::BUILTIN_OP_END, diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 0c7f9ce83cc4..10a466bda073 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -1063,6 +1063,93 @@ def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16), def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)), (A2_subh_h16_ll I32:$src1, I32:$src2)>; +let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in +def S2_parityp: ALU64Inst<(outs IntRegs:$Rd), + (ins DoubleRegs:$Rs, DoubleRegs:$Rt), + "$Rd = parity($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> { + bits<5> Rd; + bits<5> Rs; + bits<5> Rt; + + let IClass = 0b1101; + let Inst{27-24} = 0b0000; + let Inst{20-16} = Rs; + let Inst{12-8} = Rt; + let Inst{4-0} = Rd; +} + +let hasNewValue = 1, opNewValue = 0, hasSideEffects = 0 in +class T_XTYPE_MIN_MAX < bit isMax, bit isUnsigned > + : ALU64Inst < (outs IntRegs:$Rd), (ins IntRegs:$Rt, IntRegs:$Rs), + "$Rd = "#!if(isMax,"max","min")#!if(isUnsigned,"u","") + #"($Rt, $Rs)", [], "", ALU64_tc_2_SLOT23> { + bits<5> Rd; + bits<5> Rt; + bits<5> Rs; + + let IClass = 0b1101; + + let Inst{27-23} = 0b01011; + let Inst{22-21} = !if(isMax, 0b10, 0b01); + let Inst{7} = isUnsigned; + let Inst{4-0} = Rd; + let Inst{12-8} = !if(isMax, Rs, Rt); + let Inst{20-16} = !if(isMax, Rt, Rs); + } + +let isCodeGenOnly = 0 in { +def A2_min : T_XTYPE_MIN_MAX < 0, 0 >; +def A2_minu : T_XTYPE_MIN_MAX < 0, 1 >; +def A2_max : T_XTYPE_MIN_MAX < 1, 0 >; +def A2_maxu : T_XTYPE_MIN_MAX < 1, 1 >; +} + +// Here, depending on the operand being selected, we'll either generate a +// min or max instruction. +// Ex: +// (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected +// is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'. +// (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value +// is selected and the corresponding HexagonInst is passed in 'SwapInst'. + +multiclass T_MinMax_pats { + def: Pat<(select (i1 (Op (VT RC:$src1), (VT RC:$src2))), + (VT RC:$src1), (VT RC:$src2)), + (Inst RC:$src1, RC:$src2)>; + def: Pat<(select (i1 (Op (VT RC:$src1), (VT RC:$src2))), + (VT RC:$src2), (VT RC:$src1)), + (SwapInst RC:$src1, RC:$src2)>; +} + + +multiclass MinMax_pats { + defm: T_MinMax_pats; + + def: Pat<(sext_inreg (i32 (select (i1 (Op (i32 PositiveHalfWord:$src1), + (i32 PositiveHalfWord:$src2))), + (i32 PositiveHalfWord:$src1), + (i32 PositiveHalfWord:$src2))), i16), + (Inst IntRegs:$src1, IntRegs:$src2)>; + + def: Pat<(sext_inreg (i32 (select (i1 (Op (i32 PositiveHalfWord:$src1), + (i32 PositiveHalfWord:$src2))), + (i32 PositiveHalfWord:$src2), + (i32 PositiveHalfWord:$src1))), i16), + (SwapInst IntRegs:$src1, IntRegs:$src2)>; +} + +let AddedComplexity = 200 in { + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; + defm: MinMax_pats; +} + def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2), "$dst = add($src1, $src2)", diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index 70a1381b50b5..82b417ebbf7b 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -144,3 +144,8 @@ def CRRegs : RegisterClass<"Hexagon", [i32], 32, (sequence "M%u", 0, 1), PC, GP)> { let Size = 32; } + +def PositiveHalfWord : PatLeaf<(i32 IntRegs:$a), +[{ + return isPositiveHalfWord(N); +}]>; diff --git a/llvm/test/MC/Disassembler/Hexagon/xtype_alu.txt b/llvm/test/MC/Disassembler/Hexagon/xtype_alu.txt index b5f8cbc1aeb6..821ea6e3cd2d 100644 --- a/llvm/test/MC/Disassembler/Hexagon/xtype_alu.txt +++ b/llvm/test/MC/Disassembler/Hexagon/xtype_alu.txt @@ -24,6 +24,14 @@ # CHECK: r17 = add(r21.h, r31.l):sat:<<16 0xf1 0xd5 0x5f 0xd5 # CHECK: r17 = add(r21.h, r31.h):sat:<<16 +0x11 0xdf 0xd5 0xd5 +# CHECK: r17 = max(r21, r31) +0x91 0xdf 0xd5 0xd5 +# CHECK: r17 = maxu(r21, r31) +0x11 0xd5 0xbf 0xd5 +# CHECK: r17 = min(r21, r31) +0x91 0xd5 0xbf 0xd5 +# CHECK: r17 = minu(r21, r31) 0x11 0xd5 0x3f 0xd5 # CHECK: r17 = sub(r21.l, r31.l) 0x51 0xd5 0x3f 0xd5 diff --git a/llvm/test/MC/Disassembler/Hexagon/xtype_bit.txt b/llvm/test/MC/Disassembler/Hexagon/xtype_bit.txt new file mode 100644 index 000000000000..d0f63770d6b8 --- /dev/null +++ b/llvm/test/MC/Disassembler/Hexagon/xtype_bit.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s + +0x11 0xde 0x14 0xd0 +# CHECK: r17 = parity(r21:20, r31:30) \ No newline at end of file