1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[Hexagon] Adding xtype parity, min, minu, max, maxu instructions.

llvm-svn: 223693
This commit is contained in:
Colin LeMahieu 2014-12-08 21:19:18 +00:00
parent 5ae76f5dc5
commit e3767ba748
6 changed files with 122 additions and 0 deletions

View File

@ -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<ConstantSDNode>(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;
}
}

View File

@ -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,

View File

@ -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 <PatFrag Op, RegisterClass RC, ValueType VT,
InstHexagon Inst, InstHexagon SwapInst> {
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 <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
defm: T_MinMax_pats<Op, IntRegs, i32, Inst, SwapInst>;
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<setge, A2_max, A2_min>;
defm: MinMax_pats<setgt, A2_max, A2_min>;
defm: MinMax_pats<setle, A2_min, A2_max>;
defm: MinMax_pats<setlt, A2_min, A2_max>;
defm: MinMax_pats<setuge, A2_maxu, A2_minu>;
defm: MinMax_pats<setugt, A2_maxu, A2_minu>;
defm: MinMax_pats<setule, A2_minu, A2_maxu>;
defm: MinMax_pats<setult, A2_minu, A2_maxu>;
}
def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
DoubleRegs:$src2),
"$dst = add($src1, $src2)",

View File

@ -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);
}]>;

View File

@ -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

View File

@ -0,0 +1,4 @@
# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s
0x11 0xde 0x14 0xd0
# CHECK: r17 = parity(r21:20, r31:30)