nv50/ir: add preliminary support for SHLADD
This instruction is available since SM20 (Fermi) and allow to do (a << b) + c in one shot. In some situations, IMAD should be replaced by SHLADD when b is a power of 2, and ADD+SHL should be replaced by SHLADD as well. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
652874754a
commit
85132c7453
|
@ -57,6 +57,7 @@ enum operation
|
||||||
OP_MAD,
|
OP_MAD,
|
||||||
OP_FMA,
|
OP_FMA,
|
||||||
OP_SAD, // abs(src0 - src1) + src2
|
OP_SAD, // abs(src0 - src1) + src2
|
||||||
|
OP_SHLADD,
|
||||||
OP_ABS,
|
OP_ABS,
|
||||||
OP_NEG,
|
OP_NEG,
|
||||||
OP_NOT,
|
OP_NOT,
|
||||||
|
|
|
@ -86,6 +86,7 @@ const char *operationStr[OP_LAST + 1] =
|
||||||
"mad",
|
"mad",
|
||||||
"fma",
|
"fma",
|
||||||
"sad",
|
"sad",
|
||||||
|
"shladd",
|
||||||
"abs",
|
"abs",
|
||||||
"neg",
|
"neg",
|
||||||
"not",
|
"not",
|
||||||
|
|
|
@ -30,7 +30,7 @@ const uint8_t Target::operationSrcNr[] =
|
||||||
0, 0, // NOP, PHI
|
0, 0, // NOP, PHI
|
||||||
0, 0, 0, 0, // UNION, SPLIT, MERGE, CONSTRAINT
|
0, 0, 0, 0, // UNION, SPLIT, MERGE, CONSTRAINT
|
||||||
1, 1, 2, // MOV, LOAD, STORE
|
1, 1, 2, // MOV, LOAD, STORE
|
||||||
2, 2, 2, 2, 2, 3, 3, 3, // ADD, SUB, MUL, DIV, MOD, MAD, FMA, SAD
|
2, 2, 2, 2, 2, 3, 3, 3, 3, // ADD, SUB, MUL, DIV, MOD, MAD, FMA, SAD, SHLADD
|
||||||
1, 1, 1, // ABS, NEG, NOT
|
1, 1, 1, // ABS, NEG, NOT
|
||||||
2, 2, 2, 2, 2, // AND, OR, XOR, SHL, SHR
|
2, 2, 2, 2, 2, // AND, OR, XOR, SHL, SHR
|
||||||
2, 2, 1, // MAX, MIN, SAT
|
2, 2, 1, // MAX, MIN, SAT
|
||||||
|
@ -70,10 +70,10 @@ const OpClass Target::operationClass[] =
|
||||||
OPCLASS_MOVE,
|
OPCLASS_MOVE,
|
||||||
OPCLASS_LOAD,
|
OPCLASS_LOAD,
|
||||||
OPCLASS_STORE,
|
OPCLASS_STORE,
|
||||||
// ADD, SUB, MUL; DIV, MOD; MAD, FMA, SAD
|
// ADD, SUB, MUL; DIV, MOD; MAD, FMA, SAD, SHLADD
|
||||||
OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
|
OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
|
||||||
OPCLASS_ARITH, OPCLASS_ARITH,
|
OPCLASS_ARITH, OPCLASS_ARITH,
|
||||||
OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
|
OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH, OPCLASS_ARITH,
|
||||||
// ABS, NEG; NOT, AND, OR, XOR; SHL, SHR
|
// ABS, NEG; NOT, AND, OR, XOR; SHL, SHR
|
||||||
OPCLASS_CONVERT, OPCLASS_CONVERT,
|
OPCLASS_CONVERT, OPCLASS_CONVERT,
|
||||||
OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC,
|
OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC, OPCLASS_LOGIC,
|
||||||
|
|
|
@ -115,12 +115,12 @@ void TargetNV50::initOpInfo()
|
||||||
{
|
{
|
||||||
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN, SET_AND, SET_OR, SET_XOR,
|
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN, SET_AND, SET_OR, SET_XOR,
|
||||||
// SET, SELP, SLCT
|
// SET, SELP, SLCT
|
||||||
0x0670ca00, 0x0000003f, 0x00000000, 0x00000000
|
0x0ce0ca00, 0x0000007e, 0x00000000, 0x00000000
|
||||||
};
|
};
|
||||||
static const uint32_t shortForm[(OP_LAST + 31) / 32] =
|
static const uint32_t shortForm[(OP_LAST + 31) / 32] =
|
||||||
{
|
{
|
||||||
// MOV, ADD, SUB, MUL, MAD, SAD, RCP, L/PINTERP, TEX, TXF
|
// MOV, ADD, SUB, MUL, MAD, SAD, RCP, L/PINTERP, TEX, TXF
|
||||||
0x00014e40, 0x00000040, 0x00000930, 0x00000000
|
0x00014e40, 0x00000080, 0x00001260, 0x00000000
|
||||||
};
|
};
|
||||||
static const operation noDestList[] =
|
static const operation noDestList[] =
|
||||||
{
|
{
|
||||||
|
@ -438,6 +438,7 @@ TargetNV50::isOpSupported(operation op, DataType ty) const
|
||||||
case OP_EXTBF:
|
case OP_EXTBF:
|
||||||
case OP_EXIT: // want exit modifier instead (on NOP if required)
|
case OP_EXIT: // want exit modifier instead (on NOP if required)
|
||||||
case OP_MEMBAR:
|
case OP_MEMBAR:
|
||||||
|
case OP_SHLADD:
|
||||||
return false;
|
return false;
|
||||||
case OP_SAD:
|
case OP_SAD:
|
||||||
return ty == TYPE_S32;
|
return ty == TYPE_S32;
|
||||||
|
|
|
@ -105,6 +105,7 @@ static const struct opProperties _initProps[] =
|
||||||
{ OP_MAX, 0x3, 0x3, 0x0, 0x0, 0x2, 0x2 },
|
{ OP_MAX, 0x3, 0x3, 0x0, 0x0, 0x2, 0x2 },
|
||||||
{ OP_MIN, 0x3, 0x3, 0x0, 0x0, 0x2, 0x2 },
|
{ OP_MIN, 0x3, 0x3, 0x0, 0x0, 0x2, 0x2 },
|
||||||
{ OP_MAD, 0x7, 0x0, 0x0, 0x8, 0x6, 0x2 | 0x8 }, // special c[] constraint
|
{ OP_MAD, 0x7, 0x0, 0x0, 0x8, 0x6, 0x2 | 0x8 }, // special c[] constraint
|
||||||
|
{ OP_SHLADD, 0x5, 0x0, 0x0, 0x0, 0x4, 0x6 },
|
||||||
{ OP_MADSP, 0x0, 0x0, 0x0, 0x0, 0x6, 0x2 },
|
{ OP_MADSP, 0x0, 0x0, 0x0, 0x0, 0x6, 0x2 },
|
||||||
{ OP_ABS, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 },
|
{ OP_ABS, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 },
|
||||||
{ OP_NEG, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0 },
|
{ OP_NEG, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0 },
|
||||||
|
@ -158,13 +159,13 @@ void TargetNVC0::initOpInfo()
|
||||||
{
|
{
|
||||||
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN, SET_AND, SET_OR, SET_XOR,
|
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN, SET_AND, SET_OR, SET_XOR,
|
||||||
// SET, SELP, SLCT
|
// SET, SELP, SLCT
|
||||||
0x0670ca00, 0x0000003f, 0x00000000, 0x00000000
|
0x0ce0ca00, 0x0000007e, 0x00000000, 0x00000000
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t shortForm[(OP_LAST + 31) / 32] =
|
static const uint32_t shortForm[(OP_LAST + 31) / 32] =
|
||||||
{
|
{
|
||||||
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN
|
// ADD, MUL, MAD, FMA, AND, OR, XOR, MAX, MIN
|
||||||
0x0670ca00, 0x00000000, 0x00000000, 0x00000000
|
0x0ce0ca00, 0x00000000, 0x00000000, 0x00000000
|
||||||
};
|
};
|
||||||
|
|
||||||
static const operation noDest[] =
|
static const operation noDest[] =
|
||||||
|
@ -451,6 +452,12 @@ TargetNVC0::isModSupported(const Instruction *insn, int s, Modifier mod) const
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
return insn->src(1).mod.neg() ? false : true;
|
return insn->src(1).mod.neg() ? false : true;
|
||||||
break;
|
break;
|
||||||
|
case OP_SHLADD:
|
||||||
|
if (s == 1)
|
||||||
|
return false;
|
||||||
|
if (insn->src(s ? 0 : 2).mod.neg())
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue