nouveau: avoid LTO ODR warning (v2)
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_target_nv50.cpp
index a0fb14444d2d875c370aa558799d212f028a4e31..0f041bac3c87493b49da0a999bdc9f8e2928d351 100644 (file)
@@ -66,7 +66,7 @@ TargetNV50::getBuiltinOffset(int builtin) const
    return 0;
 }
 
-struct opProperties
+struct nv50_opProperties
 {
    operation op;
    unsigned int mNeg    : 4;
@@ -79,7 +79,7 @@ struct opProperties
    unsigned int fImm    : 3;
 };
 
-static const struct opProperties _initProps[] =
+static const struct nv50_opProperties _initProps[] =
 {
    //           neg  abs  not  sat  c[]  s[], a[], imm
    { OP_ADD,    0x3, 0x0, 0x0, 0x8, 0x2, 0x1, 0x1, 0x2 },
@@ -99,6 +99,7 @@ static const struct opProperties _initProps[] =
    { OP_SET,    0x3, 0x3, 0x0, 0x0, 0x2, 0x1, 0x1, 0x0 },
    { OP_PREEX2, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
    { OP_PRESIN, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+   { OP_EX2,    0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0 },
    { OP_LG2,    0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
    { OP_RCP,    0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
    { OP_RSQ,    0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
@@ -110,15 +111,15 @@ void TargetNV50::initOpInfo()
 {
    unsigned int i, j;
 
-   static const uint32_t commutative[(OP_LAST + 31) / 32] =
+   static const operation commutativeList[] =
    {
-      // ADD,MAD,MUL,AND,OR,XOR,MAX,MIN
-      0x0670ca00, 0x0000003f, 0x00000000, 0x00000000
+      OP_ADD, OP_MUL, OP_MAD, OP_FMA, OP_AND, OP_OR, OP_XOR, OP_MAX, OP_MIN,
+      OP_SET_AND, OP_SET_OR, OP_SET_XOR, OP_SET, OP_SELP, OP_SLCT
    };
-   static const uint32_t shortForm[(OP_LAST + 31) / 32] =
+   static const operation shortFormList[] =
    {
-      // MOV,ADD,SUB,MUL,MAD,SAD,L/PINTERP,RCP,TEX,TXF
-      0x00014e40, 0x00000040, 0x00000930, 0x00000000
+      OP_MOV, OP_ADD, OP_SUB, OP_MUL, OP_MAD, OP_SAD, OP_RCP, OP_LINTERP,
+      OP_PINTERP, OP_TEX, OP_TXF
    };
    static const operation noDestList[] =
    {
@@ -155,19 +156,23 @@ void TargetNV50::initOpInfo()
 
       opInfo[i].hasDest = 1;
       opInfo[i].vector = (i >= OP_TEX && i <= OP_TEXCSAA);
-      opInfo[i].commutative = (commutative[i / 32] >> (i % 32)) & 1;
+      opInfo[i].commutative = false; /* set below */
       opInfo[i].pseudo = (i < OP_MOV);
       opInfo[i].predicate = !opInfo[i].pseudo;
       opInfo[i].flow = (i >= OP_BRA && i <= OP_JOIN);
-      opInfo[i].minEncSize = (shortForm[i / 32] & (1 << (i % 32))) ? 4 : 8;
+      opInfo[i].minEncSize = 8; /* set below */
    }
-   for (i = 0; i < sizeof(noDestList) / sizeof(noDestList[0]); ++i)
+   for (i = 0; i < ARRAY_SIZE(commutativeList); ++i)
+      opInfo[commutativeList[i]].commutative = true;
+   for (i = 0; i < ARRAY_SIZE(shortFormList); ++i)
+      opInfo[shortFormList[i]].minEncSize = 4;
+   for (i = 0; i < ARRAY_SIZE(noDestList); ++i)
       opInfo[noDestList[i]].hasDest = 0;
-   for (i = 0; i < sizeof(noPredList) / sizeof(noPredList[0]); ++i)
+   for (i = 0; i < ARRAY_SIZE(noPredList); ++i)
       opInfo[noPredList[i]].predicate = 0;
 
-   for (i = 0; i < sizeof(_initProps) / sizeof(_initProps[0]); ++i) {
-      const struct opProperties *prop = &_initProps[i];
+   for (i = 0; i < ARRAY_SIZE(_initProps); ++i) {
+      const struct nv50_opProperties *prop = &_initProps[i];
 
       for (int s = 0; s < 3; ++s) {
          if (prop->mNeg & (1 << s))
@@ -198,7 +203,7 @@ TargetNV50::getFileSize(DataFile file) const
 {
    switch (file) {
    case FILE_NULL:          return 0;
-   case FILE_GPR:           return 256; // in 16-bit units **
+   case FILE_GPR:           return 254; // in 16-bit units **
    case FILE_PREDICATE:     return 0;
    case FILE_FLAGS:         return 4;
    case FILE_ADDRESS:       return 4;
@@ -206,6 +211,7 @@ TargetNV50::getFileSize(DataFile file) const
    case FILE_MEMORY_CONST:  return 65536;
    case FILE_SHADER_INPUT:  return 0x200;
    case FILE_SHADER_OUTPUT: return 0x200;
+   case FILE_MEMORY_BUFFER: return 0xffffffff;
    case FILE_MEMORY_GLOBAL: return 0xffffffff;
    case FILE_MEMORY_SHARED: return 16 << 10;
    case FILE_MEMORY_LOCAL:  return 48 << 10;
@@ -251,6 +257,7 @@ TargetNV50::getSVAddress(DataFile shaderFile, const Symbol *sym) const
    case SV_NTID:
       return 0x2 + 2 * sym->reg.data.sv.index;
    case SV_TID:
+   case SV_COMBINED_TID:
       return 0;
    case SV_SAMPLE_POS:
       return 0; /* sample position is handled differently */
@@ -384,13 +391,29 @@ TargetNV50::insnCanLoad(const Instruction *i, int s,
    return true;
 }
 
+bool
+TargetNV50::insnCanLoadOffset(const Instruction *i, int s, int offset) const
+{
+   if (!i->src(s).isIndirect(0))
+      return true;
+   offset += i->src(s).get()->reg.data.offset;
+   if (i->op == OP_LOAD || i->op == OP_STORE) {
+      // There are some restrictions in theory, but in practice they're never
+      // going to be hit. When we enable shared/global memory, this will
+      // become more important.
+      return true;
+   }
+   return offset >= 0 && offset <= (int32_t)(127 * i->src(s).get()->reg.size);
+}
+
 bool
 TargetNV50::isAccessSupported(DataFile file, DataType ty) const
 {
    if (ty == TYPE_B96 || ty == TYPE_NONE)
       return false;
    if (typeSizeof(ty) > 4)
-      return (file == FILE_MEMORY_LOCAL) || (file == FILE_MEMORY_GLOBAL);
+      return (file == FILE_MEMORY_LOCAL) || (file == FILE_MEMORY_GLOBAL) ||
+             (file == FILE_MEMORY_BUFFER);
    return true;
 }
 
@@ -419,6 +442,8 @@ TargetNV50::isOpSupported(operation op, DataType ty) const
    case OP_EXTBF:
    case OP_EXIT: // want exit modifier instead (on NOP if required)
    case OP_MEMBAR:
+   case OP_SHLADD:
+   case OP_XMAD:
       return false;
    case OP_SAD:
       return ty == TYPE_S32;
@@ -460,7 +485,7 @@ TargetNV50::isModSupported(const Instruction *insn, int s, Modifier mod) const
          return false;
       }
    }
-   if (s >= 3)
+   if (s >= opInfo[insn->op].srcNr || s >= 3)
       return false;
    return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
 }
@@ -493,6 +518,7 @@ int TargetNV50::getLatency(const Instruction *i) const
       switch (i->src(0).getFile()) {
       case FILE_MEMORY_LOCAL:
       case FILE_MEMORY_GLOBAL:
+      case FILE_MEMORY_BUFFER:
          return 100; // really 400 to 800
       default:
          return 22;
@@ -573,6 +599,8 @@ TargetNV50::parseDriverInfo(const struct nv50_ir_prog_info *info)
       wposMask = 0x8;
       sysvalLocation[SV_POSITION] = 0;
    }
+
+   Target::parseDriverInfo(info);
 }
 
 } // namespace nv50_ir