LValues& convert(nir_dest *);
SVSemantic convert(nir_intrinsic_op);
Value* convert(nir_load_const_instr*, uint8_t);
- LValues& convert(nir_register *);
LValues& convert(nir_ssa_def *);
Value* getSrc(nir_alu_src *, uint8_t component = 0);
- Value* getSrc(nir_register *, uint8_t);
Value* getSrc(nir_src *, uint8_t, bool indirect = false);
Value* getSrc(nir_ssa_def *, uint8_t);
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);
+ assert(insn->dest.dest.is_ssa);
+ return getDType(insn->op, insn->dest.dest.ssa.bit_size);
}
DataType
break;
}
- if (insn->dest.is_ssa)
- return typeOfSize(insn->dest.ssa.bit_size / 8, isFloat, isSigned);
- else
- return typeOfSize(insn->dest.reg.reg->bit_size / 8, isFloat, isSigned);
+ assert(insn->dest.is_ssa);
+ return typeOfSize(insn->dest.ssa.bit_size / 8, isFloat, isSigned);
}
DataType
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;
+ assert(src.is_ssa);
+ const uint8_t bitSize = src.ssa->bit_size;
DataType ty = typeOfSize(bitSize / 8, isFloat, isSigned);
if (ty == TYPE_NONE) {
Converter::LValues&
Converter::convert(nir_dest *dest)
{
- if (dest->is_ssa)
- return convert(&dest->ssa);
- if (dest->reg.indirect) {
- ERROR("no support for indirects.");
- assert(false);
- }
- return convert(dest->reg.reg);
-}
-
-Converter::LValues&
-Converter::convert(nir_register *reg)
-{
- assert(!reg->num_array_elems);
-
- NirDefMap::iterator it = regDefs.find(reg->index);
- if (it != regDefs.end())
- return it->second;
-
- LValues newDef(reg->num_components);
- for (uint8_t i = 0; i < reg->num_components; i++)
- newDef[i] = getScratch(std::max(4, reg->bit_size / 8));
- return regDefs[reg->index] = newDef;
+ assert(dest->is_ssa);
+ return convert(&dest->ssa);
}
Converter::LValues&
}
Value*
-Converter::getSrc(nir_register *reg, uint8_t idx)
-{
- NirDefMap::iterator it = regDefs.find(reg->index);
- if (it == regDefs.end())
- return convert(reg)[idx];
- return it->second[idx];
-}
-
-Value*
Converter::getSrc(nir_src *src, uint8_t idx, bool indirect)
{
- if (src->is_ssa)
- return getSrc(src->ssa, idx);
-
- if (src->reg.indirect) {
- if (indirect)
- return getSrc(src->reg.indirect, idx);
- ERROR("no support for indirects.");
- assert(false);
- return NULL;
- }
-
- return getSrc(src->reg.reg, idx);
+ assert(src->is_ssa);
+ return getSrc(src->ssa, idx);
}
Value*
unsigned dest_components = nir_intrinsic_dest_components(insn);
switch (op) {
+ case nir_intrinsic_decl_reg: {
+ const unsigned reg_index = insn->dest.ssa.index;
+ const unsigned bit_size = nir_intrinsic_bit_size(insn);
+ const unsigned num_components = nir_intrinsic_num_components(insn);
+ assert(nir_intrinsic_num_array_elems(insn) == 0);
+
+ LValues newDef(num_components);
+ for (uint8_t c = 0; c < num_components; c++)
+ newDef[c] = getScratch(std::max(4u, bit_size / 8));
+
+ assert(regDefs.find(reg_index) == regDefs.end());
+ regDefs[reg_index] = newDef;
+ break;
+ }
+
+ case nir_intrinsic_load_reg: {
+ const unsigned reg_index = insn->src[0].ssa->index;
+ NirDefMap::iterator it = regDefs.find(reg_index);
+ assert(it != regDefs.end());
+ LValues &src = it->second;
+
+ DataType dType = getDType(insn);
+ LValues &newDefs = convert(&insn->dest);
+ for (uint8_t c = 0; c < insn->num_components; c++)
+ mkMov(newDefs[c], src[c], dType);
+ break;
+ }
+
+ case nir_intrinsic_store_reg: {
+ const unsigned reg_index = insn->src[1].ssa->index;
+ NirDefMap::iterator it = regDefs.find(reg_index);
+ assert(it != regDefs.end());
+ LValues &dst = it->second;
+
+ DataType dType = Converter::getSType(insn->src[0], false, false);
+
+ const nir_component_mask_t write_mask = nir_intrinsic_write_mask(insn);
+ for (uint8_t c = 0u; c < insn->num_components; c++) {
+ if (!((1u << c) & write_mask))
+ continue;
+
+ Value *src = getSrc(&insn->src[0], c);
+ mkMov(dst[c], src, dType);
+ }
+ break;
+ }
+
case nir_intrinsic_store_output:
case nir_intrinsic_store_per_vertex_output: {
Value *indirect;
NIR_PASS_V(nir, nir_lower_bool_to_int32);
NIR_PASS_V(nir, nir_lower_bit_size, Converter::lowerBitSizeCB, this);
- NIR_PASS_V(nir, nir_convert_from_ssa, true, false);
+ NIR_PASS_V(nir, nir_convert_from_ssa, true, true);
// Garbage collect dead instructions
nir_sweep(nir);