nv50/ir/nir: add nir type helper functions
authorKarol Herbst <kherbst@redhat.com>
Mon, 18 Dec 2017 02:57:06 +0000 (03:57 +0100)
committerKarol Herbst <kherbst@redhat.com>
Sun, 17 Mar 2019 09:33:28 +0000 (10:33 +0100)
v4: treat imul as unsigned
v5: remove pointless !!
v7: inot is unsigned as well
v8: don't require C++11 features
v9: convert to C++ style comments
    improve formatting
    print error in all cases where codegen doesn't support a given type

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Pierre Moreau <pierre.morrow@free.fr>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp

index f7908876e96bc3c60bc8826560e4e114b7d2b327..2ac6d8c1d07f9828c9d9f848a4c22bafb107c3c0 100644 (file)
@@ -86,6 +86,18 @@ private:
    uint32_t getIndirect(nir_src *, uint8_t, Value *&);
    uint32_t getIndirect(nir_intrinsic_instr *, uint8_t s, uint8_t c, Value *&);
 
+   bool isFloatType(nir_alu_type);
+   bool isSignedType(nir_alu_type);
+   bool isResultFloat(nir_op);
+   bool isResultSigned(nir_op);
+
+   DataType getDType(nir_alu_instr *);
+   DataType getDType(nir_intrinsic_instr *);
+   DataType getDType(nir_op, uint8_t);
+
+   std::vector<DataType> getSTypes(nir_alu_instr *);
+   DataType getSType(nir_src &, bool isFloat, bool isSigned);
+
    nir_shader *nir;
 
    NirDefMap ssaDefs;
@@ -96,6 +108,121 @@ Converter::Converter(Program *prog, nir_shader *nir, nv50_ir_prog_info *info)
    : ConverterCommon(prog, info),
      nir(nir) {}
 
+bool
+Converter::isFloatType(nir_alu_type type)
+{
+   return nir_alu_type_get_base_type(type) == nir_type_float;
+}
+
+bool
+Converter::isSignedType(nir_alu_type type)
+{
+   return nir_alu_type_get_base_type(type) == nir_type_int;
+}
+
+bool
+Converter::isResultFloat(nir_op op)
+{
+   const nir_op_info &info = nir_op_infos[op];
+   if (info.output_type != nir_type_invalid)
+      return isFloatType(info.output_type);
+
+   ERROR("isResultFloat not implemented for %s\n", nir_op_infos[op].name);
+   assert(false);
+   return true;
+}
+
+bool
+Converter::isResultSigned(nir_op op)
+{
+   switch (op) {
+   // there is no umul and we get wrong results if we treat all muls as signed
+   case nir_op_imul:
+   case nir_op_inot:
+      return false;
+   default:
+      const nir_op_info &info = nir_op_infos[op];
+      if (info.output_type != nir_type_invalid)
+         return isSignedType(info.output_type);
+      ERROR("isResultSigned not implemented for %s\n", nir_op_infos[op].name);
+      assert(false);
+      return true;
+   }
+}
+
+DataType
+Converter::getDType(nir_alu_instr *insn)
+{
+   if (insn->dest.dest.is_ssa)
+      return getDType(insn->op, insn->dest.dest.ssa.bit_size);
+   else
+      return getDType(insn->op, insn->dest.dest.reg.reg->bit_size);
+}
+
+DataType
+Converter::getDType(nir_intrinsic_instr *insn)
+{
+   if (insn->dest.is_ssa)
+      return typeOfSize(insn->dest.ssa.bit_size / 8, false, false);
+   else
+      return typeOfSize(insn->dest.reg.reg->bit_size / 8, false, false);
+}
+
+DataType
+Converter::getDType(nir_op op, uint8_t bitSize)
+{
+   DataType ty = typeOfSize(bitSize / 8, isResultFloat(op), isResultSigned(op));
+   if (ty == TYPE_NONE) {
+      ERROR("couldn't get Type for op %s with bitSize %u\n", nir_op_infos[op].name, bitSize);
+      assert(false);
+   }
+   return ty;
+}
+
+std::vector<DataType>
+Converter::getSTypes(nir_alu_instr *insn)
+{
+   const nir_op_info &info = nir_op_infos[insn->op];
+   std::vector<DataType> res(info.num_inputs);
+
+   for (uint8_t i = 0; i < info.num_inputs; ++i) {
+      if (info.input_types[i] != nir_type_invalid) {
+         res[i] = getSType(insn->src[i].src, isFloatType(info.input_types[i]), isSignedType(info.input_types[i]));
+      } else {
+         ERROR("getSType not implemented for %s idx %u\n", info.name, i);
+         assert(false);
+         res[i] = TYPE_NONE;
+         break;
+      }
+   }
+
+   return res;
+}
+
+DataType
+Converter::getSType(nir_src &src, bool isFloat, bool isSigned)
+{
+   uint8_t bitSize;
+   if (src.is_ssa)
+      bitSize = src.ssa->bit_size;
+   else
+      bitSize = src.reg.reg->bit_size;
+
+   DataType ty = typeOfSize(bitSize / 8, isFloat, isSigned);
+   if (ty == TYPE_NONE) {
+      const char *str;
+      if (isFloat)
+         str = "float";
+      else if (isSigned)
+         str = "int";
+      else
+         str = "uint";
+      ERROR("couldn't get Type for %s with bitSize %u\n", str, bitSize);
+      assert(false);
+   }
+   return ty;
+}
+
 Converter::LValues&
 Converter::convert(nir_dest *dest)
 {