typedef struct nir_builder {
nir_cursor cursor;
+ /* Whether new ALU instructions will be marked "exact" */
+ bool exact;
+
nir_shader *shader;
nir_function_impl *impl;
} nir_builder;
nir_builder_init(nir_builder *build, nir_function_impl *impl)
{
memset(build, 0, sizeof(*build));
+ build->exact = false;
build->impl = impl;
build->shader = impl->function->shader;
}
{
build->shader = nir_shader_create(mem_ctx, stage, options);
nir_function *func = nir_function_create(build->shader, "main");
+ build->exact = false;
build->impl = nir_function_impl_create(func);
build->cursor = nir_after_cf_list(&build->impl->body);
}
}
static inline nir_ssa_def *
-nir_ssa_undef(nir_builder *build, unsigned num_components)
+nir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size)
{
nir_ssa_undef_instr *undef =
- nir_ssa_undef_instr_create(build->shader, num_components);
+ nir_ssa_undef_instr_create(build->shader, num_components, bit_size);
if (!undef)
return NULL;
- nir_instr_insert(nir_before_block(nir_start_block(build->impl)),
- &undef->instr);
+ nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr);
return &undef->def;
}
static inline nir_ssa_def *
-nir_build_imm(nir_builder *build, unsigned num_components, nir_const_value value)
+nir_build_imm(nir_builder *build, unsigned num_components,
+ unsigned bit_size, nir_const_value value)
{
nir_load_const_instr *load_const =
- nir_load_const_instr_create(build->shader, num_components);
+ nir_load_const_instr_create(build->shader, num_components, bit_size);
if (!load_const)
return NULL;
nir_const_value v;
memset(&v, 0, sizeof(v));
- v.f[0] = x;
+ v.f32[0] = x;
+
+ return nir_build_imm(build, 1, 32, v);
+}
+
+static inline nir_ssa_def *
+nir_imm_double(nir_builder *build, double x)
+{
+ nir_const_value v;
+
+ memset(&v, 0, sizeof(v));
+ v.f64[0] = x;
- return nir_build_imm(build, 1, v);
+ return nir_build_imm(build, 1, 64, v);
}
static inline nir_ssa_def *
nir_const_value v;
memset(&v, 0, sizeof(v));
- v.f[0] = x;
- v.f[1] = y;
- v.f[2] = z;
- v.f[3] = w;
+ v.f32[0] = x;
+ v.f32[1] = y;
+ v.f32[2] = z;
+ v.f32[3] = w;
- return nir_build_imm(build, 4, v);
+ return nir_build_imm(build, 4, 32, v);
}
static inline nir_ssa_def *
nir_const_value v;
memset(&v, 0, sizeof(v));
- v.i[0] = x;
+ v.i32[0] = x;
- return nir_build_imm(build, 1, v);
+ return nir_build_imm(build, 1, 32, v);
}
static inline nir_ssa_def *
nir_const_value v;
memset(&v, 0, sizeof(v));
- v.i[0] = x;
- v.i[1] = y;
- v.i[2] = z;
- v.i[3] = w;
+ v.i32[0] = x;
+ v.i32[1] = y;
+ v.i32[2] = z;
+ v.i32[3] = w;
- return nir_build_imm(build, 4, v);
+ return nir_build_imm(build, 4, 32, v);
}
static inline nir_ssa_def *
if (!instr)
return NULL;
+ instr->exact = build->exact;
+
instr->src[0].src = nir_src_for_ssa(src0);
if (src1)
instr->src[1].src = nir_src_for_ssa(src1);
}
assert(num_components != 0);
+ /* Figure out the bitwidth based on the source bitwidth if the instruction
+ * is variable-width.
+ */
+ unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type);
+ if (bit_size == 0) {
+ for (unsigned i = 0; i < op_info->num_inputs; i++) {
+ unsigned src_bit_size = instr->src[i].src.ssa->bit_size;
+ if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) {
+ if (bit_size)
+ assert(src_bit_size == bit_size);
+ else
+ bit_size = src_bit_size;
+ } else {
+ assert(src_bit_size ==
+ nir_alu_type_get_type_size(op_info->input_types[i]));
+ }
+ }
+ }
+
/* Make sure we don't swizzle from outside of our source vector (like if a
* scalar value was passed into a multiply with a vector).
*/
}
}
- nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, NULL);
+ nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components,
+ bit_size, NULL);
instr->dest.write_mask = (1 << num_components) - 1;
nir_builder_instr_insert(build, &instr->instr);
return &instr->dest.dest.ssa;
}
-#define ALU1(op) \
-static inline nir_ssa_def * \
-nir_##op(nir_builder *build, nir_ssa_def *src0) \
-{ \
- return nir_build_alu(build, nir_op_##op, src0, NULL, NULL, NULL); \
-}
-
-#define ALU2(op) \
-static inline nir_ssa_def * \
-nir_##op(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) \
-{ \
- return nir_build_alu(build, nir_op_##op, src0, src1, NULL, NULL); \
-}
-
-#define ALU3(op) \
-static inline nir_ssa_def * \
-nir_##op(nir_builder *build, nir_ssa_def *src0, \
- nir_ssa_def *src1, nir_ssa_def *src2) \
-{ \
- return nir_build_alu(build, nir_op_##op, src0, src1, src2, NULL); \
-}
-
-#define ALU4(op) \
-static inline nir_ssa_def * \
-nir_##op(nir_builder *build, nir_ssa_def *src0, \
- nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) \
-{ \
- return nir_build_alu(build, nir_op_##op, src0, src1, src2, src3); \
-}
-
#include "nir_builder_opcodes.h"
static inline nir_ssa_def *
nir_fmov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
{
nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_fmov);
- nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, NULL);
+ nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components,
+ nir_src_bit_size(src.src), NULL);
+ mov->exact = build->exact;
mov->dest.write_mask = (1 << num_components) - 1;
mov->src[0] = src;
nir_builder_instr_insert(build, &mov->instr);
nir_imov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
{
nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_imov);
- nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, NULL);
+ nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components,
+ nir_src_bit_size(src.src), NULL);
+ mov->exact = build->exact;
mov->dest.write_mask = (1 << num_components) - 1;
mov->src[0] = src;
nir_builder_instr_insert(build, &mov->instr);
* Construct an fmov or imov that reswizzles the source's components.
*/
static inline nir_ssa_def *
-nir_swizzle(nir_builder *build, nir_ssa_def *src, unsigned swiz[4],
+nir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned swiz[4],
unsigned num_components, bool use_fmov)
{
nir_alu_src alu_src = { NIR_SRC_INIT };
nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_var);
load->num_components = num_components;
load->variables[0] = nir_deref_var_create(load, var);
- nir_ssa_dest_init(&load->instr, &load->dest, num_components, NULL);
+ nir_ssa_dest_init(&load->instr, &load->dest, num_components,
+ glsl_get_bit_size(var->type), NULL);
nir_builder_instr_insert(build, &load->instr);
return &load->dest.ssa;
}
load->num_components = nir_intrinsic_infos[op].dest_components;
load->const_index[0] = index;
nir_ssa_dest_init(&load->instr, &load->dest,
- nir_intrinsic_infos[op].dest_components, NULL);
+ nir_intrinsic_infos[op].dest_components, 32, NULL);
nir_builder_instr_insert(build, &load->instr);
return &load->dest.ssa;
}