101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2014-2015 Broadcom
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#ifndef NIR_BUILDER_H
2501e04c3fSmrg#define NIR_BUILDER_H
2601e04c3fSmrg
2701e04c3fSmrg#include "nir_control_flow.h"
287e102996Smaya#include "util/bitscan.h"
2901e04c3fSmrg#include "util/half_float.h"
3001e04c3fSmrg
3101e04c3fSmrgstruct exec_list;
3201e04c3fSmrg
3301e04c3fSmrgtypedef struct nir_builder {
3401e04c3fSmrg   nir_cursor cursor;
3501e04c3fSmrg
3601e04c3fSmrg   /* Whether new ALU instructions will be marked "exact" */
3701e04c3fSmrg   bool exact;
3801e04c3fSmrg
397ec681f3Smrg   /* Whether to run divergence analysis on inserted instructions (loop merge
407ec681f3Smrg    * and header phis are not updated). */
417ec681f3Smrg   bool update_divergence;
427ec681f3Smrg
4301e04c3fSmrg   nir_shader *shader;
4401e04c3fSmrg   nir_function_impl *impl;
4501e04c3fSmrg} nir_builder;
4601e04c3fSmrg
4701e04c3fSmrgstatic inline void
4801e04c3fSmrgnir_builder_init(nir_builder *build, nir_function_impl *impl)
4901e04c3fSmrg{
5001e04c3fSmrg   memset(build, 0, sizeof(*build));
5101e04c3fSmrg   build->exact = false;
5201e04c3fSmrg   build->impl = impl;
5301e04c3fSmrg   build->shader = impl->function->shader;
5401e04c3fSmrg}
5501e04c3fSmrg
567ec681f3Smrgstatic inline nir_builder MUST_CHECK PRINTFLIKE(3, 4)
577ec681f3Smrgnir_builder_init_simple_shader(gl_shader_stage stage,
587ec681f3Smrg                               const nir_shader_compiler_options *options,
597ec681f3Smrg                               const char *name, ...)
6001e04c3fSmrg{
617ec681f3Smrg   nir_builder b;
627ec681f3Smrg
637ec681f3Smrg   memset(&b, 0, sizeof(b));
647ec681f3Smrg   b.shader = nir_shader_create(NULL, stage, options, NULL);
657ec681f3Smrg
667ec681f3Smrg   if (name) {
677ec681f3Smrg      va_list args;
687ec681f3Smrg      va_start(args, name);
697ec681f3Smrg      b.shader->info.name = ralloc_vasprintf(b.shader, name, args);
707ec681f3Smrg      va_end(args);
717ec681f3Smrg   }
727ec681f3Smrg
737ec681f3Smrg   nir_function *func = nir_function_create(b.shader, "main");
747e102996Smaya   func->is_entrypoint = true;
757ec681f3Smrg   b.exact = false;
767ec681f3Smrg   b.impl = nir_function_impl_create(func);
777ec681f3Smrg   b.cursor = nir_after_cf_list(&b.impl->body);
787ec681f3Smrg
797ec681f3Smrg   return b;
807ec681f3Smrg}
817ec681f3Smrg
827ec681f3Smrgtypedef bool (*nir_instr_pass_cb)(struct nir_builder *, nir_instr *, void *);
837ec681f3Smrg
847ec681f3Smrg/**
857ec681f3Smrg * Iterates over all the instructions in a NIR shader and calls the given pass
867ec681f3Smrg * on them.
877ec681f3Smrg *
887ec681f3Smrg * The pass should return true if it modified the shader.  In that case, only
897ec681f3Smrg * the preserved metadata flags will be preserved in the function impl.
907ec681f3Smrg *
917ec681f3Smrg * The builder will be initialized to point at the function impl, but its
927ec681f3Smrg * cursor is unset.
937ec681f3Smrg */
947ec681f3Smrgstatic inline bool
957ec681f3Smrgnir_shader_instructions_pass(nir_shader *shader,
967ec681f3Smrg                             nir_instr_pass_cb pass,
977ec681f3Smrg                             nir_metadata preserved,
987ec681f3Smrg                             void *cb_data)
997ec681f3Smrg{
1007ec681f3Smrg   bool progress = false;
1017ec681f3Smrg
1027ec681f3Smrg   nir_foreach_function(function, shader) {
1037ec681f3Smrg      if (!function->impl)
1047ec681f3Smrg         continue;
1057ec681f3Smrg
1067ec681f3Smrg      bool func_progress = false;
1077ec681f3Smrg      nir_builder b;
1087ec681f3Smrg      nir_builder_init(&b, function->impl);
1097ec681f3Smrg
1107ec681f3Smrg      nir_foreach_block_safe(block, function->impl) {
1117ec681f3Smrg         nir_foreach_instr_safe(instr, block) {
1127ec681f3Smrg            func_progress |= pass(&b, instr, cb_data);
1137ec681f3Smrg         }
1147ec681f3Smrg      }
1157ec681f3Smrg
1167ec681f3Smrg      if (func_progress) {
1177ec681f3Smrg         nir_metadata_preserve(function->impl, preserved);
1187ec681f3Smrg         progress = true;
1197ec681f3Smrg      } else {
1207ec681f3Smrg         nir_metadata_preserve(function->impl, nir_metadata_all);
1217ec681f3Smrg      }
1227ec681f3Smrg   }
1237ec681f3Smrg
1247ec681f3Smrg   return progress;
12501e04c3fSmrg}
12601e04c3fSmrg
12701e04c3fSmrgstatic inline void
12801e04c3fSmrgnir_builder_instr_insert(nir_builder *build, nir_instr *instr)
12901e04c3fSmrg{
13001e04c3fSmrg   nir_instr_insert(build->cursor, instr);
13101e04c3fSmrg
1327ec681f3Smrg   if (build->update_divergence)
1337ec681f3Smrg      nir_update_instr_divergence(build->shader, instr);
1347ec681f3Smrg
13501e04c3fSmrg   /* Move the cursor forward. */
13601e04c3fSmrg   build->cursor = nir_after_instr(instr);
13701e04c3fSmrg}
13801e04c3fSmrg
13901e04c3fSmrgstatic inline nir_instr *
14001e04c3fSmrgnir_builder_last_instr(nir_builder *build)
14101e04c3fSmrg{
14201e04c3fSmrg   assert(build->cursor.option == nir_cursor_after_instr);
14301e04c3fSmrg   return build->cursor.instr;
14401e04c3fSmrg}
14501e04c3fSmrg
14601e04c3fSmrgstatic inline void
14701e04c3fSmrgnir_builder_cf_insert(nir_builder *build, nir_cf_node *cf)
14801e04c3fSmrg{
14901e04c3fSmrg   nir_cf_node_insert(build->cursor, cf);
15001e04c3fSmrg}
15101e04c3fSmrg
15201e04c3fSmrgstatic inline bool
15301e04c3fSmrgnir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node)
15401e04c3fSmrg{
15501e04c3fSmrg   nir_block *block = nir_cursor_current_block(build->cursor);
15601e04c3fSmrg   for (nir_cf_node *n = &block->cf_node; n; n = n->parent) {
15701e04c3fSmrg      if (n == cf_node)
15801e04c3fSmrg         return true;
15901e04c3fSmrg   }
16001e04c3fSmrg   return false;
16101e04c3fSmrg}
16201e04c3fSmrg
16301e04c3fSmrgstatic inline nir_if *
1647ec681f3Smrgnir_push_if_src(nir_builder *build, nir_src condition)
16501e04c3fSmrg{
16601e04c3fSmrg   nir_if *nif = nir_if_create(build->shader);
1677ec681f3Smrg   nif->condition = condition;
16801e04c3fSmrg   nir_builder_cf_insert(build, &nif->cf_node);
16901e04c3fSmrg   build->cursor = nir_before_cf_list(&nif->then_list);
17001e04c3fSmrg   return nif;
17101e04c3fSmrg}
17201e04c3fSmrg
1737ec681f3Smrgstatic inline nir_if *
1747ec681f3Smrgnir_push_if(nir_builder *build, nir_ssa_def *condition)
1757ec681f3Smrg{
1767ec681f3Smrg   return nir_push_if_src(build, nir_src_for_ssa(condition));
1777ec681f3Smrg}
1787ec681f3Smrg
17901e04c3fSmrgstatic inline nir_if *
18001e04c3fSmrgnir_push_else(nir_builder *build, nir_if *nif)
18101e04c3fSmrg{
18201e04c3fSmrg   if (nif) {
18301e04c3fSmrg      assert(nir_builder_is_inside_cf(build, &nif->cf_node));
18401e04c3fSmrg   } else {
18501e04c3fSmrg      nir_block *block = nir_cursor_current_block(build->cursor);
18601e04c3fSmrg      nif = nir_cf_node_as_if(block->cf_node.parent);
18701e04c3fSmrg   }
18801e04c3fSmrg   build->cursor = nir_before_cf_list(&nif->else_list);
18901e04c3fSmrg   return nif;
19001e04c3fSmrg}
19101e04c3fSmrg
19201e04c3fSmrgstatic inline void
19301e04c3fSmrgnir_pop_if(nir_builder *build, nir_if *nif)
19401e04c3fSmrg{
19501e04c3fSmrg   if (nif) {
19601e04c3fSmrg      assert(nir_builder_is_inside_cf(build, &nif->cf_node));
19701e04c3fSmrg   } else {
19801e04c3fSmrg      nir_block *block = nir_cursor_current_block(build->cursor);
19901e04c3fSmrg      nif = nir_cf_node_as_if(block->cf_node.parent);
20001e04c3fSmrg   }
20101e04c3fSmrg   build->cursor = nir_after_cf_node(&nif->cf_node);
20201e04c3fSmrg}
20301e04c3fSmrg
20401e04c3fSmrgstatic inline nir_ssa_def *
20501e04c3fSmrgnir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def)
20601e04c3fSmrg{
20701e04c3fSmrg   nir_block *block = nir_cursor_current_block(build->cursor);
20801e04c3fSmrg   nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node));
20901e04c3fSmrg
21001e04c3fSmrg   nir_phi_instr *phi = nir_phi_instr_create(build->shader);
2117ec681f3Smrg   nir_phi_instr_add_src(phi, nir_if_last_then_block(nif), nir_src_for_ssa(then_def));
2127ec681f3Smrg   nir_phi_instr_add_src(phi, nir_if_last_else_block(nif), nir_src_for_ssa(else_def));
21301e04c3fSmrg
21401e04c3fSmrg   assert(then_def->num_components == else_def->num_components);
21501e04c3fSmrg   assert(then_def->bit_size == else_def->bit_size);
21601e04c3fSmrg   nir_ssa_dest_init(&phi->instr, &phi->dest,
21701e04c3fSmrg                     then_def->num_components, then_def->bit_size, NULL);
21801e04c3fSmrg
21901e04c3fSmrg   nir_builder_instr_insert(build, &phi->instr);
22001e04c3fSmrg
22101e04c3fSmrg   return &phi->dest.ssa;
22201e04c3fSmrg}
22301e04c3fSmrg
22401e04c3fSmrgstatic inline nir_loop *
22501e04c3fSmrgnir_push_loop(nir_builder *build)
22601e04c3fSmrg{
22701e04c3fSmrg   nir_loop *loop = nir_loop_create(build->shader);
22801e04c3fSmrg   nir_builder_cf_insert(build, &loop->cf_node);
22901e04c3fSmrg   build->cursor = nir_before_cf_list(&loop->body);
23001e04c3fSmrg   return loop;
23101e04c3fSmrg}
23201e04c3fSmrg
23301e04c3fSmrgstatic inline void
23401e04c3fSmrgnir_pop_loop(nir_builder *build, nir_loop *loop)
23501e04c3fSmrg{
23601e04c3fSmrg   if (loop) {
23701e04c3fSmrg      assert(nir_builder_is_inside_cf(build, &loop->cf_node));
23801e04c3fSmrg   } else {
23901e04c3fSmrg      nir_block *block = nir_cursor_current_block(build->cursor);
24001e04c3fSmrg      loop = nir_cf_node_as_loop(block->cf_node.parent);
24101e04c3fSmrg   }
24201e04c3fSmrg   build->cursor = nir_after_cf_node(&loop->cf_node);
24301e04c3fSmrg}
24401e04c3fSmrg
24501e04c3fSmrgstatic inline nir_ssa_def *
24601e04c3fSmrgnir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size)
24701e04c3fSmrg{
24801e04c3fSmrg   nir_ssa_undef_instr *undef =
24901e04c3fSmrg      nir_ssa_undef_instr_create(build->shader, num_components, bit_size);
25001e04c3fSmrg   if (!undef)
25101e04c3fSmrg      return NULL;
25201e04c3fSmrg
25301e04c3fSmrg   nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr);
2547ec681f3Smrg   if (build->update_divergence)
2557ec681f3Smrg      nir_update_instr_divergence(build->shader, &undef->instr);
25601e04c3fSmrg
25701e04c3fSmrg   return &undef->def;
25801e04c3fSmrg}
25901e04c3fSmrg
26001e04c3fSmrgstatic inline nir_ssa_def *
26101e04c3fSmrgnir_build_imm(nir_builder *build, unsigned num_components,
2627e102996Smaya              unsigned bit_size, const nir_const_value *value)
26301e04c3fSmrg{
26401e04c3fSmrg   nir_load_const_instr *load_const =
26501e04c3fSmrg      nir_load_const_instr_create(build->shader, num_components, bit_size);
26601e04c3fSmrg   if (!load_const)
26701e04c3fSmrg      return NULL;
26801e04c3fSmrg
2697e102996Smaya   memcpy(load_const->value, value, sizeof(nir_const_value) * num_components);
2707e102996Smaya
2717e102996Smaya   nir_builder_instr_insert(build, &load_const->instr);
2727e102996Smaya
2737e102996Smaya   return &load_const->def;
2747e102996Smaya}
2757e102996Smaya
2767e102996Smayastatic inline nir_ssa_def *
2777e102996Smayanir_imm_zero(nir_builder *build, unsigned num_components, unsigned bit_size)
2787e102996Smaya{
2797e102996Smaya   nir_load_const_instr *load_const =
2807e102996Smaya      nir_load_const_instr_create(build->shader, num_components, bit_size);
2817e102996Smaya
2827e102996Smaya   /* nir_load_const_instr_create uses rzalloc so it's already zero */
28301e04c3fSmrg
28401e04c3fSmrg   nir_builder_instr_insert(build, &load_const->instr);
28501e04c3fSmrg
28601e04c3fSmrg   return &load_const->def;
28701e04c3fSmrg}
28801e04c3fSmrg
28901e04c3fSmrgstatic inline nir_ssa_def *
2907ec681f3Smrgnir_imm_boolN_t(nir_builder *build, bool x, unsigned bit_size)
29101e04c3fSmrg{
2927ec681f3Smrg   nir_const_value v = nir_const_value_for_bool(x, bit_size);
2937ec681f3Smrg   return nir_build_imm(build, 1, bit_size, &v);
2947ec681f3Smrg}
29501e04c3fSmrg
2967ec681f3Smrgstatic inline nir_ssa_def *
2977ec681f3Smrgnir_imm_bool(nir_builder *build, bool x)
2987ec681f3Smrg{
2997ec681f3Smrg   return nir_imm_boolN_t(build, x, 1);
30001e04c3fSmrg}
30101e04c3fSmrg
30201e04c3fSmrgstatic inline nir_ssa_def *
30301e04c3fSmrgnir_imm_true(nir_builder *build)
30401e04c3fSmrg{
30501e04c3fSmrg   return nir_imm_bool(build, true);
30601e04c3fSmrg}
30701e04c3fSmrg
30801e04c3fSmrgstatic inline nir_ssa_def *
30901e04c3fSmrgnir_imm_false(nir_builder *build)
31001e04c3fSmrg{
31101e04c3fSmrg   return nir_imm_bool(build, false);
31201e04c3fSmrg}
31301e04c3fSmrg
31401e04c3fSmrgstatic inline nir_ssa_def *
3157ec681f3Smrgnir_imm_floatN_t(nir_builder *build, double x, unsigned bit_size)
31601e04c3fSmrg{
3177ec681f3Smrg   nir_const_value v = nir_const_value_for_float(x, bit_size);
3187ec681f3Smrg   return nir_build_imm(build, 1, bit_size, &v);
3197ec681f3Smrg}
32001e04c3fSmrg
3217ec681f3Smrgstatic inline nir_ssa_def *
3227ec681f3Smrgnir_imm_float16(nir_builder *build, float x)
3237ec681f3Smrg{
3247ec681f3Smrg   return nir_imm_floatN_t(build, x, 16);
32501e04c3fSmrg}
32601e04c3fSmrg
32701e04c3fSmrgstatic inline nir_ssa_def *
32801e04c3fSmrgnir_imm_float(nir_builder *build, float x)
32901e04c3fSmrg{
3307ec681f3Smrg   return nir_imm_floatN_t(build, x, 32);
33101e04c3fSmrg}
33201e04c3fSmrg
33301e04c3fSmrgstatic inline nir_ssa_def *
33401e04c3fSmrgnir_imm_double(nir_builder *build, double x)
33501e04c3fSmrg{
3367ec681f3Smrg   return nir_imm_floatN_t(build, x, 64);
33701e04c3fSmrg}
33801e04c3fSmrg
33901e04c3fSmrgstatic inline nir_ssa_def *
3407ec681f3Smrgnir_imm_vec2(nir_builder *build, float x, float y)
34101e04c3fSmrg{
3427ec681f3Smrg   nir_const_value v[2] = {
3437ec681f3Smrg      nir_const_value_for_float(x, 32),
3447ec681f3Smrg      nir_const_value_for_float(y, 32),
3457ec681f3Smrg   };
3467ec681f3Smrg   return nir_build_imm(build, 2, 32, v);
34701e04c3fSmrg}
34801e04c3fSmrg
3497e102996Smayastatic inline nir_ssa_def *
3507ec681f3Smrgnir_imm_vec3(nir_builder *build, float x, float y, float z)
3517e102996Smaya{
3527ec681f3Smrg   nir_const_value v[3] = {
3537ec681f3Smrg      nir_const_value_for_float(x, 32),
3547ec681f3Smrg      nir_const_value_for_float(y, 32),
3557ec681f3Smrg      nir_const_value_for_float(z, 32),
3567ec681f3Smrg   };
3577ec681f3Smrg   return nir_build_imm(build, 3, 32, v);
3587e102996Smaya}
3597e102996Smaya
36001e04c3fSmrgstatic inline nir_ssa_def *
36101e04c3fSmrgnir_imm_vec4(nir_builder *build, float x, float y, float z, float w)
36201e04c3fSmrg{
3637ec681f3Smrg   nir_const_value v[4] = {
3647ec681f3Smrg      nir_const_value_for_float(x, 32),
3657ec681f3Smrg      nir_const_value_for_float(y, 32),
3667ec681f3Smrg      nir_const_value_for_float(z, 32),
3677ec681f3Smrg      nir_const_value_for_float(w, 32),
3687ec681f3Smrg   };
36901e04c3fSmrg
37001e04c3fSmrg   return nir_build_imm(build, 4, 32, v);
37101e04c3fSmrg}
37201e04c3fSmrg
37301e04c3fSmrgstatic inline nir_ssa_def *
3747ec681f3Smrgnir_imm_vec4_16(nir_builder *build, float x, float y, float z, float w)
37501e04c3fSmrg{
3767ec681f3Smrg   nir_const_value v[4] = {
3777ec681f3Smrg      nir_const_value_for_float(x, 16),
3787ec681f3Smrg      nir_const_value_for_float(y, 16),
3797ec681f3Smrg      nir_const_value_for_float(z, 16),
3807ec681f3Smrg      nir_const_value_for_float(w, 16),
3817ec681f3Smrg   };
38201e04c3fSmrg
3837ec681f3Smrg   return nir_build_imm(build, 4, 16, v);
3847ec681f3Smrg}
38501e04c3fSmrg
3867ec681f3Smrgstatic inline nir_ssa_def *
3877ec681f3Smrgnir_imm_intN_t(nir_builder *build, uint64_t x, unsigned bit_size)
3887ec681f3Smrg{
3897ec681f3Smrg   nir_const_value v = nir_const_value_for_raw_uint(x, bit_size);
3907ec681f3Smrg   return nir_build_imm(build, 1, bit_size, &v);
39101e04c3fSmrg}
39201e04c3fSmrg
39301e04c3fSmrgstatic inline nir_ssa_def *
39401e04c3fSmrgnir_imm_int(nir_builder *build, int x)
39501e04c3fSmrg{
3967ec681f3Smrg   return nir_imm_intN_t(build, x, 32);
39701e04c3fSmrg}
39801e04c3fSmrg
39901e04c3fSmrgstatic inline nir_ssa_def *
40001e04c3fSmrgnir_imm_int64(nir_builder *build, int64_t x)
40101e04c3fSmrg{
4027ec681f3Smrg   return nir_imm_intN_t(build, x, 64);
40301e04c3fSmrg}
40401e04c3fSmrg
40501e04c3fSmrgstatic inline nir_ssa_def *
4067ec681f3Smrgnir_imm_ivec2(nir_builder *build, int x, int y)
40701e04c3fSmrg{
4087ec681f3Smrg   nir_const_value v[2] = {
4097ec681f3Smrg      nir_const_value_for_int(x, 32),
4107ec681f3Smrg      nir_const_value_for_int(y, 32),
4117ec681f3Smrg   };
41201e04c3fSmrg
4137ec681f3Smrg   return nir_build_imm(build, 2, 32, v);
41401e04c3fSmrg}
41501e04c3fSmrg
41601e04c3fSmrgstatic inline nir_ssa_def *
4177ec681f3Smrgnir_imm_ivec3(nir_builder *build, int x, int y, int z)
41801e04c3fSmrg{
4197ec681f3Smrg   nir_const_value v[3] = {
4207ec681f3Smrg      nir_const_value_for_int(x, 32),
4217ec681f3Smrg      nir_const_value_for_int(y, 32),
4227ec681f3Smrg      nir_const_value_for_int(z, 32),
4237ec681f3Smrg   };
42401e04c3fSmrg
4257ec681f3Smrg   return nir_build_imm(build, 3, 32, v);
42601e04c3fSmrg}
42701e04c3fSmrg
42801e04c3fSmrgstatic inline nir_ssa_def *
4297ec681f3Smrgnir_imm_ivec4(nir_builder *build, int x, int y, int z, int w)
43001e04c3fSmrg{
4317ec681f3Smrg   nir_const_value v[4] = {
4327ec681f3Smrg      nir_const_value_for_int(x, 32),
4337ec681f3Smrg      nir_const_value_for_int(y, 32),
4347ec681f3Smrg      nir_const_value_for_int(z, 32),
4357ec681f3Smrg      nir_const_value_for_int(w, 32),
4367ec681f3Smrg   };
4377ec681f3Smrg
4387ec681f3Smrg   return nir_build_imm(build, 4, 32, v);
4397e102996Smaya}
44001e04c3fSmrg
4417e102996Smayastatic inline nir_ssa_def *
4427e102996Smayanir_builder_alu_instr_finish_and_insert(nir_builder *build, nir_alu_instr *instr)
4437e102996Smaya{
4447e102996Smaya   const nir_op_info *op_info = &nir_op_infos[instr->op];
44501e04c3fSmrg
4467e102996Smaya   instr->exact = build->exact;
44701e04c3fSmrg
44801e04c3fSmrg   /* Guess the number of components the destination temporary should have
44901e04c3fSmrg    * based on our input sizes, if it's not fixed for the op.
45001e04c3fSmrg    */
45101e04c3fSmrg   unsigned num_components = op_info->output_size;
45201e04c3fSmrg   if (num_components == 0) {
45301e04c3fSmrg      for (unsigned i = 0; i < op_info->num_inputs; i++) {
45401e04c3fSmrg         if (op_info->input_sizes[i] == 0)
45501e04c3fSmrg            num_components = MAX2(num_components,
45601e04c3fSmrg                                  instr->src[i].src.ssa->num_components);
45701e04c3fSmrg      }
45801e04c3fSmrg   }
45901e04c3fSmrg   assert(num_components != 0);
46001e04c3fSmrg
46101e04c3fSmrg   /* Figure out the bitwidth based on the source bitwidth if the instruction
46201e04c3fSmrg    * is variable-width.
46301e04c3fSmrg    */
46401e04c3fSmrg   unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type);
46501e04c3fSmrg   if (bit_size == 0) {
46601e04c3fSmrg      for (unsigned i = 0; i < op_info->num_inputs; i++) {
46701e04c3fSmrg         unsigned src_bit_size = instr->src[i].src.ssa->bit_size;
46801e04c3fSmrg         if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) {
46901e04c3fSmrg            if (bit_size)
47001e04c3fSmrg               assert(src_bit_size == bit_size);
47101e04c3fSmrg            else
47201e04c3fSmrg               bit_size = src_bit_size;
47301e04c3fSmrg         } else {
47401e04c3fSmrg            assert(src_bit_size ==
47501e04c3fSmrg               nir_alu_type_get_type_size(op_info->input_types[i]));
47601e04c3fSmrg         }
47701e04c3fSmrg      }
47801e04c3fSmrg   }
47901e04c3fSmrg
48001e04c3fSmrg   /* When in doubt, assume 32. */
48101e04c3fSmrg   if (bit_size == 0)
48201e04c3fSmrg      bit_size = 32;
48301e04c3fSmrg
48401e04c3fSmrg   /* Make sure we don't swizzle from outside of our source vector (like if a
48501e04c3fSmrg    * scalar value was passed into a multiply with a vector).
48601e04c3fSmrg    */
48701e04c3fSmrg   for (unsigned i = 0; i < op_info->num_inputs; i++) {
48801e04c3fSmrg      for (unsigned j = instr->src[i].src.ssa->num_components;
48901e04c3fSmrg           j < NIR_MAX_VEC_COMPONENTS; j++) {
49001e04c3fSmrg         instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1;
49101e04c3fSmrg      }
49201e04c3fSmrg   }
49301e04c3fSmrg
49401e04c3fSmrg   nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components,
49501e04c3fSmrg                     bit_size, NULL);
49601e04c3fSmrg   instr->dest.write_mask = (1 << num_components) - 1;
49701e04c3fSmrg
49801e04c3fSmrg   nir_builder_instr_insert(build, &instr->instr);
49901e04c3fSmrg
50001e04c3fSmrg   return &instr->dest.dest.ssa;
50101e04c3fSmrg}
50201e04c3fSmrg
5037e102996Smayastatic inline nir_ssa_def *
5047e102996Smayanir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0,
5057e102996Smaya              nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3)
5067e102996Smaya{
5077e102996Smaya   nir_alu_instr *instr = nir_alu_instr_create(build->shader, op);
5087e102996Smaya   if (!instr)
5097e102996Smaya      return NULL;
5107e102996Smaya
5117e102996Smaya   instr->src[0].src = nir_src_for_ssa(src0);
5127e102996Smaya   if (src1)
5137e102996Smaya      instr->src[1].src = nir_src_for_ssa(src1);
5147e102996Smaya   if (src2)
5157e102996Smaya      instr->src[2].src = nir_src_for_ssa(src2);
5167e102996Smaya   if (src3)
5177e102996Smaya      instr->src[3].src = nir_src_for_ssa(src3);
5187e102996Smaya
5197e102996Smaya   return nir_builder_alu_instr_finish_and_insert(build, instr);
5207e102996Smaya}
5217e102996Smaya
5227e102996Smaya/* for the couple special cases with more than 4 src args: */
5237e102996Smayastatic inline nir_ssa_def *
5247e102996Smayanir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs)
5257e102996Smaya{
5267e102996Smaya   const nir_op_info *op_info = &nir_op_infos[op];
5277e102996Smaya   nir_alu_instr *instr = nir_alu_instr_create(build->shader, op);
5287e102996Smaya   if (!instr)
5297e102996Smaya      return NULL;
5307e102996Smaya
5317e102996Smaya   for (unsigned i = 0; i < op_info->num_inputs; i++)
5327e102996Smaya      instr->src[i].src = nir_src_for_ssa(srcs[i]);
5337e102996Smaya
5347e102996Smaya   return nir_builder_alu_instr_finish_and_insert(build, instr);
5357e102996Smaya}
5367e102996Smaya
5377ec681f3Smrg/* Generic builder for system values. */
5387ec681f3Smrgstatic inline nir_ssa_def *
5397ec681f3Smrgnir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index,
5407ec681f3Smrg                      unsigned num_components, unsigned bit_size)
5417ec681f3Smrg{
5427ec681f3Smrg   nir_intrinsic_instr *load = nir_intrinsic_instr_create(build->shader, op);
5437ec681f3Smrg   if (nir_intrinsic_infos[op].dest_components > 0)
5447ec681f3Smrg      assert(num_components == nir_intrinsic_infos[op].dest_components);
5457ec681f3Smrg   else
5467ec681f3Smrg      load->num_components = num_components;
5477ec681f3Smrg   load->const_index[0] = index;
5487ec681f3Smrg
5497ec681f3Smrg   nir_ssa_dest_init(&load->instr, &load->dest,
5507ec681f3Smrg                     num_components, bit_size, NULL);
5517ec681f3Smrg   nir_builder_instr_insert(build, &load->instr);
5527ec681f3Smrg   return &load->dest.ssa;
5537ec681f3Smrg}
5547ec681f3Smrg
55501e04c3fSmrg#include "nir_builder_opcodes.h"
5567ec681f3Smrg#undef nir_deref_mode_is
55701e04c3fSmrg
55801e04c3fSmrgstatic inline nir_ssa_def *
55901e04c3fSmrgnir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components)
56001e04c3fSmrg{
5617e102996Smaya   return nir_build_alu_src_arr(build, nir_op_vec(num_components), comp);
56201e04c3fSmrg}
56301e04c3fSmrg
56401e04c3fSmrgstatic inline nir_ssa_def *
5657ec681f3Smrgnir_mov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
5667ec681f3Smrg{
5677ec681f3Smrg   assert(!src.abs && !src.negate);
5687ec681f3Smrg   if (src.src.is_ssa && src.src.ssa->num_components == num_components) {
5697ec681f3Smrg      bool any_swizzles = false;
5707ec681f3Smrg      for (unsigned i = 0; i < num_components; i++) {
5717ec681f3Smrg         if (src.swizzle[i] != i)
5727ec681f3Smrg            any_swizzles = true;
5737ec681f3Smrg      }
5747ec681f3Smrg      if (!any_swizzles)
5757ec681f3Smrg         return src.src.ssa;
5767ec681f3Smrg   }
57701e04c3fSmrg
5787ec681f3Smrg   nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov);
57901e04c3fSmrg   nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components,
58001e04c3fSmrg                     nir_src_bit_size(src.src), NULL);
58101e04c3fSmrg   mov->exact = build->exact;
58201e04c3fSmrg   mov->dest.write_mask = (1 << num_components) - 1;
58301e04c3fSmrg   mov->src[0] = src;
58401e04c3fSmrg   nir_builder_instr_insert(build, &mov->instr);
58501e04c3fSmrg
58601e04c3fSmrg   return &mov->dest.dest.ssa;
58701e04c3fSmrg}
58801e04c3fSmrg
58901e04c3fSmrg/**
5907ec681f3Smrg * Construct a mov that reswizzles the source's components.
59101e04c3fSmrg */
59201e04c3fSmrgstatic inline nir_ssa_def *
59301e04c3fSmrgnir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned *swiz,
5947ec681f3Smrg            unsigned num_components)
59501e04c3fSmrg{
59601e04c3fSmrg   assert(num_components <= NIR_MAX_VEC_COMPONENTS);
59701e04c3fSmrg   nir_alu_src alu_src = { NIR_SRC_INIT };
59801e04c3fSmrg   alu_src.src = nir_src_for_ssa(src);
5997e102996Smaya
6007e102996Smaya   bool is_identity_swizzle = true;
6017e102996Smaya   for (unsigned i = 0; i < num_components && i < NIR_MAX_VEC_COMPONENTS; i++) {
6027e102996Smaya      if (swiz[i] != i)
6037e102996Smaya         is_identity_swizzle = false;
60401e04c3fSmrg      alu_src.swizzle[i] = swiz[i];
6057e102996Smaya   }
6067e102996Smaya
6077e102996Smaya   if (num_components == src->num_components && is_identity_swizzle)
6087e102996Smaya      return src;
60901e04c3fSmrg
6107ec681f3Smrg   return nir_mov_alu(build, alu_src, num_components);
61101e04c3fSmrg}
61201e04c3fSmrg
61301e04c3fSmrg/* Selects the right fdot given the number of components in each source. */
61401e04c3fSmrgstatic inline nir_ssa_def *
61501e04c3fSmrgnir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1)
61601e04c3fSmrg{
61701e04c3fSmrg   assert(src0->num_components == src1->num_components);
61801e04c3fSmrg   switch (src0->num_components) {
61901e04c3fSmrg   case 1: return nir_fmul(build, src0, src1);
62001e04c3fSmrg   case 2: return nir_fdot2(build, src0, src1);
62101e04c3fSmrg   case 3: return nir_fdot3(build, src0, src1);
62201e04c3fSmrg   case 4: return nir_fdot4(build, src0, src1);
6237ec681f3Smrg   case 5: return nir_fdot5(build, src0, src1);
6247ec681f3Smrg   case 8: return nir_fdot8(build, src0, src1);
6257ec681f3Smrg   case 16: return nir_fdot16(build, src0, src1);
62601e04c3fSmrg   default:
62701e04c3fSmrg      unreachable("bad component size");
62801e04c3fSmrg   }
62901e04c3fSmrg
63001e04c3fSmrg   return NULL;
63101e04c3fSmrg}
63201e04c3fSmrg
6337ec681f3Smrgstatic inline nir_ssa_def *
6347ec681f3Smrgnir_ball_iequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1)
6357ec681f3Smrg{
6367ec681f3Smrg   switch (src0->num_components) {
6377ec681f3Smrg   case 1: return nir_ieq(b, src0, src1);
6387ec681f3Smrg   case 2: return nir_ball_iequal2(b, src0, src1);
6397ec681f3Smrg   case 3: return nir_ball_iequal3(b, src0, src1);
6407ec681f3Smrg   case 4: return nir_ball_iequal4(b, src0, src1);
6417ec681f3Smrg   case 5: return nir_ball_iequal5(b, src0, src1);
6427ec681f3Smrg   case 8: return nir_ball_iequal8(b, src0, src1);
6437ec681f3Smrg   case 16: return nir_ball_iequal16(b, src0, src1);
6447ec681f3Smrg   default:
6457ec681f3Smrg      unreachable("bad component size");
6467ec681f3Smrg   }
6477ec681f3Smrg}
6487ec681f3Smrg
6497ec681f3Smrgstatic inline nir_ssa_def *
6507ec681f3Smrgnir_ball(nir_builder *b, nir_ssa_def *src)
6517ec681f3Smrg{
6527ec681f3Smrg   return nir_ball_iequal(b, src, nir_imm_true(b));
6537ec681f3Smrg}
6547ec681f3Smrg
65501e04c3fSmrgstatic inline nir_ssa_def *
65601e04c3fSmrgnir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1)
65701e04c3fSmrg{
65801e04c3fSmrg   switch (src0->num_components) {
65901e04c3fSmrg   case 1: return nir_ine(b, src0, src1);
66001e04c3fSmrg   case 2: return nir_bany_inequal2(b, src0, src1);
66101e04c3fSmrg   case 3: return nir_bany_inequal3(b, src0, src1);
66201e04c3fSmrg   case 4: return nir_bany_inequal4(b, src0, src1);
6637ec681f3Smrg   case 5: return nir_bany_inequal5(b, src0, src1);
6647ec681f3Smrg   case 8: return nir_bany_inequal8(b, src0, src1);
6657ec681f3Smrg   case 16: return nir_bany_inequal16(b, src0, src1);
66601e04c3fSmrg   default:
66701e04c3fSmrg      unreachable("bad component size");
66801e04c3fSmrg   }
66901e04c3fSmrg}
67001e04c3fSmrg
67101e04c3fSmrgstatic inline nir_ssa_def *
67201e04c3fSmrgnir_bany(nir_builder *b, nir_ssa_def *src)
67301e04c3fSmrg{
67401e04c3fSmrg   return nir_bany_inequal(b, src, nir_imm_false(b));
67501e04c3fSmrg}
67601e04c3fSmrg
67701e04c3fSmrgstatic inline nir_ssa_def *
67801e04c3fSmrgnir_channel(nir_builder *b, nir_ssa_def *def, unsigned c)
67901e04c3fSmrg{
6807ec681f3Smrg   return nir_swizzle(b, def, &c, 1);
68101e04c3fSmrg}
68201e04c3fSmrg
68301e04c3fSmrgstatic inline nir_ssa_def *
68401e04c3fSmrgnir_channels(nir_builder *b, nir_ssa_def *def, nir_component_mask_t mask)
68501e04c3fSmrg{
68601e04c3fSmrg   unsigned num_channels = 0, swizzle[NIR_MAX_VEC_COMPONENTS] = { 0 };
68701e04c3fSmrg
68801e04c3fSmrg   for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
68901e04c3fSmrg      if ((mask & (1 << i)) == 0)
69001e04c3fSmrg         continue;
69101e04c3fSmrg      swizzle[num_channels++] = i;
69201e04c3fSmrg   }
69301e04c3fSmrg
6947ec681f3Smrg   return nir_swizzle(b, def, swizzle, num_channels);
69501e04c3fSmrg}
69601e04c3fSmrg
6977e102996Smayastatic inline nir_ssa_def *
6987ec681f3Smrg_nir_select_from_array_helper(nir_builder *b, nir_ssa_def **arr,
6997ec681f3Smrg                              nir_ssa_def *idx,
7007ec681f3Smrg                              unsigned start, unsigned end)
7017e102996Smaya{
7027e102996Smaya   if (start == end - 1) {
7037ec681f3Smrg      return arr[start];
7047e102996Smaya   } else {
7057e102996Smaya      unsigned mid = start + (end - start) / 2;
7067ec681f3Smrg      return nir_bcsel(b, nir_ilt(b, idx, nir_imm_intN_t(b, mid, idx->bit_size)),
7077ec681f3Smrg                       _nir_select_from_array_helper(b, arr, idx, start, mid),
7087ec681f3Smrg                       _nir_select_from_array_helper(b, arr, idx, mid, end));
7097e102996Smaya   }
7107e102996Smaya}
7117e102996Smaya
7127ec681f3Smrgstatic inline nir_ssa_def *
7137ec681f3Smrgnir_select_from_ssa_def_array(nir_builder *b, nir_ssa_def **arr,
7147ec681f3Smrg                              unsigned arr_len, nir_ssa_def *idx)
7157ec681f3Smrg{
7167ec681f3Smrg   return _nir_select_from_array_helper(b, arr, idx, 0, arr_len);
7177ec681f3Smrg}
7187ec681f3Smrg
7197e102996Smayastatic inline nir_ssa_def *
7207e102996Smayanir_vector_extract(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *c)
7217e102996Smaya{
7227e102996Smaya   nir_src c_src = nir_src_for_ssa(c);
7237e102996Smaya   if (nir_src_is_const(c_src)) {
7247ec681f3Smrg      uint64_t c_const = nir_src_as_uint(c_src);
7257e102996Smaya      if (c_const < vec->num_components)
7267e102996Smaya         return nir_channel(b, vec, c_const);
7277e102996Smaya      else
7287e102996Smaya         return nir_ssa_undef(b, 1, vec->bit_size);
7297e102996Smaya   } else {
7307ec681f3Smrg      nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
7317ec681f3Smrg      for (unsigned i = 0; i < vec->num_components; i++)
7327ec681f3Smrg         comps[i] = nir_channel(b, vec, i);
7337ec681f3Smrg      return nir_select_from_ssa_def_array(b, comps, vec->num_components, c);
7347ec681f3Smrg   }
7357ec681f3Smrg}
7367ec681f3Smrg
7377ec681f3Smrg/** Replaces the component of `vec` specified by `c` with `scalar` */
7387ec681f3Smrgstatic inline nir_ssa_def *
7397ec681f3Smrgnir_vector_insert_imm(nir_builder *b, nir_ssa_def *vec,
7407ec681f3Smrg                      nir_ssa_def *scalar, unsigned c)
7417ec681f3Smrg{
7427ec681f3Smrg   assert(scalar->num_components == 1);
7437ec681f3Smrg   assert(c < vec->num_components);
7447ec681f3Smrg
7457ec681f3Smrg   nir_op vec_op = nir_op_vec(vec->num_components);
7467ec681f3Smrg   nir_alu_instr *vec_instr = nir_alu_instr_create(b->shader, vec_op);
7477ec681f3Smrg
7487ec681f3Smrg   for (unsigned i = 0; i < vec->num_components; i++) {
7497ec681f3Smrg      if (i == c) {
7507ec681f3Smrg         vec_instr->src[i].src = nir_src_for_ssa(scalar);
7517ec681f3Smrg         vec_instr->src[i].swizzle[0] = 0;
7527ec681f3Smrg      } else {
7537ec681f3Smrg         vec_instr->src[i].src = nir_src_for_ssa(vec);
7547ec681f3Smrg         vec_instr->src[i].swizzle[0] = i;
7557ec681f3Smrg      }
7567ec681f3Smrg   }
7577ec681f3Smrg
7587ec681f3Smrg   return nir_builder_alu_instr_finish_and_insert(b, vec_instr);
7597ec681f3Smrg}
7607ec681f3Smrg
7617ec681f3Smrg/** Replaces the component of `vec` specified by `c` with `scalar` */
7627ec681f3Smrgstatic inline nir_ssa_def *
7637ec681f3Smrgnir_vector_insert(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *scalar,
7647ec681f3Smrg                  nir_ssa_def *c)
7657ec681f3Smrg{
7667ec681f3Smrg   assert(scalar->num_components == 1);
7677ec681f3Smrg   assert(c->num_components == 1);
7687ec681f3Smrg
7697ec681f3Smrg   nir_src c_src = nir_src_for_ssa(c);
7707ec681f3Smrg   if (nir_src_is_const(c_src)) {
7717ec681f3Smrg      uint64_t c_const = nir_src_as_uint(c_src);
7727ec681f3Smrg      if (c_const < vec->num_components)
7737ec681f3Smrg         return nir_vector_insert_imm(b, vec, scalar, c_const);
7747ec681f3Smrg      else
7757ec681f3Smrg         return vec;
7767ec681f3Smrg   } else {
7777ec681f3Smrg      nir_const_value per_comp_idx_const[NIR_MAX_VEC_COMPONENTS];
7787ec681f3Smrg      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
7797ec681f3Smrg         per_comp_idx_const[i] = nir_const_value_for_int(i, c->bit_size);
7807ec681f3Smrg      nir_ssa_def *per_comp_idx =
7817ec681f3Smrg         nir_build_imm(b, vec->num_components,
7827ec681f3Smrg                       c->bit_size, per_comp_idx_const);
7837ec681f3Smrg
7847ec681f3Smrg      /* nir_builder will automatically splat out scalars to vectors so an
7857ec681f3Smrg       * insert is as simple as "if I'm the channel, replace me with the
7867ec681f3Smrg       * scalar."
7877ec681f3Smrg       */
7887ec681f3Smrg      return nir_bcsel(b, nir_ieq(b, c, per_comp_idx), scalar, vec);
7897e102996Smaya   }
7907e102996Smaya}
7917e102996Smaya
7927e102996Smayastatic inline nir_ssa_def *
7937e102996Smayanir_i2i(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size)
7947e102996Smaya{
7957e102996Smaya   if (x->bit_size == dest_bit_size)
7967e102996Smaya      return x;
7977e102996Smaya
7987e102996Smaya   switch (dest_bit_size) {
7997e102996Smaya   case 64: return nir_i2i64(build, x);
8007e102996Smaya   case 32: return nir_i2i32(build, x);
8017e102996Smaya   case 16: return nir_i2i16(build, x);
8027e102996Smaya   case 8:  return nir_i2i8(build, x);
8037e102996Smaya   default: unreachable("Invalid bit size");
8047e102996Smaya   }
8057e102996Smaya}
8067e102996Smaya
8077e102996Smayastatic inline nir_ssa_def *
8087e102996Smayanir_u2u(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size)
8097e102996Smaya{
8107e102996Smaya   if (x->bit_size == dest_bit_size)
8117e102996Smaya      return x;
8127e102996Smaya
8137e102996Smaya   switch (dest_bit_size) {
8147e102996Smaya   case 64: return nir_u2u64(build, x);
8157e102996Smaya   case 32: return nir_u2u32(build, x);
8167e102996Smaya   case 16: return nir_u2u16(build, x);
8177e102996Smaya   case 8:  return nir_u2u8(build, x);
8187e102996Smaya   default: unreachable("Invalid bit size");
8197e102996Smaya   }
8207e102996Smaya}
8217e102996Smaya
8227e102996Smayastatic inline nir_ssa_def *
8237e102996Smayanir_iadd_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
8247e102996Smaya{
8257e102996Smaya   assert(x->bit_size <= 64);
8267ec681f3Smrg   y &= BITFIELD64_MASK(x->bit_size);
8277e102996Smaya
8287e102996Smaya   if (y == 0) {
8297e102996Smaya      return x;
8307e102996Smaya   } else {
8317e102996Smaya      return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size));
8327e102996Smaya   }
8337e102996Smaya}
8347e102996Smaya
8357e102996Smayastatic inline nir_ssa_def *
8367ec681f3Smrgnir_iadd_imm_nuw(nir_builder *b, nir_ssa_def *x, uint64_t y)
8377ec681f3Smrg{
8387ec681f3Smrg   nir_ssa_def *d = nir_iadd_imm(b, x, y);
8397ec681f3Smrg   if (d != x && d->parent_instr->type == nir_instr_type_alu)
8407ec681f3Smrg      nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true;
8417ec681f3Smrg   return d;
8427ec681f3Smrg}
8437ec681f3Smrg
8447ec681f3Smrgstatic inline nir_ssa_def *
8457ec681f3Smrgnir_iadd_nuw(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
8467ec681f3Smrg{
8477ec681f3Smrg   nir_ssa_def *d = nir_iadd(b, x, y);
8487ec681f3Smrg   nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true;
8497ec681f3Smrg   return d;
8507ec681f3Smrg}
8517ec681f3Smrg
8527ec681f3Smrgstatic inline nir_ssa_def *
8537ec681f3Smrgnir_ieq_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
8547ec681f3Smrg{
8557ec681f3Smrg   return nir_ieq(build, x, nir_imm_intN_t(build, y, x->bit_size));
8567ec681f3Smrg}
8577ec681f3Smrg
8587ec681f3Smrg/* Use nir_iadd(x, -y) for reversing parameter ordering */
8597ec681f3Smrgstatic inline nir_ssa_def *
8607ec681f3Smrgnir_isub_imm(nir_builder *build, uint64_t y, nir_ssa_def *x)
8617ec681f3Smrg{
8627ec681f3Smrg   return nir_isub(build, nir_imm_intN_t(build, y, x->bit_size), x);
8637ec681f3Smrg}
8647ec681f3Smrg
8657ec681f3Smrgstatic inline nir_ssa_def *
8667ec681f3Smrg_nir_mul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y, bool amul)
8677e102996Smaya{
8687e102996Smaya   assert(x->bit_size <= 64);
8697ec681f3Smrg   y &= BITFIELD64_MASK(x->bit_size);
8707e102996Smaya
8717e102996Smaya   if (y == 0) {
8727e102996Smaya      return nir_imm_intN_t(build, 0, x->bit_size);
8737e102996Smaya   } else if (y == 1) {
8747e102996Smaya      return x;
8757ec681f3Smrg   } else if (!build->shader->options->lower_bitops &&
8767ec681f3Smrg              util_is_power_of_two_or_zero64(y)) {
8777e102996Smaya      return nir_ishl(build, x, nir_imm_int(build, ffsll(y) - 1));
8787ec681f3Smrg   } else if (amul) {
8797ec681f3Smrg      return nir_amul(build, x, nir_imm_intN_t(build, y, x->bit_size));
8807e102996Smaya   } else {
8817e102996Smaya      return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size));
8827e102996Smaya   }
8837e102996Smaya}
8847e102996Smaya
8857ec681f3Smrgstatic inline nir_ssa_def *
8867ec681f3Smrgnir_imul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
8877ec681f3Smrg{
8887ec681f3Smrg   return _nir_mul_imm(build, x, y, false);
8897ec681f3Smrg}
8907ec681f3Smrg
8917ec681f3Smrgstatic inline nir_ssa_def *
8927ec681f3Smrgnir_amul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
8937ec681f3Smrg{
8947ec681f3Smrg   return _nir_mul_imm(build, x, y, true);
8957ec681f3Smrg}
8967ec681f3Smrg
8977e102996Smayastatic inline nir_ssa_def *
8987e102996Smayanir_fadd_imm(nir_builder *build, nir_ssa_def *x, double y)
8997e102996Smaya{
9007e102996Smaya   return nir_fadd(build, x, nir_imm_floatN_t(build, y, x->bit_size));
9017e102996Smaya}
9027e102996Smaya
9037e102996Smayastatic inline nir_ssa_def *
9047e102996Smayanir_fmul_imm(nir_builder *build, nir_ssa_def *x, double y)
9057e102996Smaya{
9067e102996Smaya   return nir_fmul(build, x, nir_imm_floatN_t(build, y, x->bit_size));
9077e102996Smaya}
9087e102996Smaya
9097ec681f3Smrgstatic inline nir_ssa_def *
9107ec681f3Smrgnir_iand_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
9117ec681f3Smrg{
9127ec681f3Smrg   assert(x->bit_size <= 64);
9137ec681f3Smrg   y &= BITFIELD64_MASK(x->bit_size);
9147ec681f3Smrg
9157ec681f3Smrg   if (y == 0) {
9167ec681f3Smrg      return nir_imm_intN_t(build, 0, x->bit_size);
9177ec681f3Smrg   } else if (y == BITFIELD64_MASK(x->bit_size)) {
9187ec681f3Smrg      return x;
9197ec681f3Smrg   } else {
9207ec681f3Smrg      return nir_iand(build, x, nir_imm_intN_t(build, y, x->bit_size));
9217ec681f3Smrg   }
9227ec681f3Smrg}
9237ec681f3Smrg
9247ec681f3Smrgstatic inline nir_ssa_def *
9257ec681f3Smrgnir_ishr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y)
9267ec681f3Smrg{
9277ec681f3Smrg   if (y == 0) {
9287ec681f3Smrg      return x;
9297ec681f3Smrg   } else {
9307ec681f3Smrg      return nir_ishr(build, x, nir_imm_int(build, y));
9317ec681f3Smrg   }
9327ec681f3Smrg}
9337ec681f3Smrg
9347ec681f3Smrgstatic inline nir_ssa_def *
9357ec681f3Smrgnir_ushr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y)
9367ec681f3Smrg{
9377ec681f3Smrg   if (y == 0) {
9387ec681f3Smrg      return x;
9397ec681f3Smrg   } else {
9407ec681f3Smrg      return nir_ushr(build, x, nir_imm_int(build, y));
9417ec681f3Smrg   }
9427ec681f3Smrg}
9437ec681f3Smrg
9447ec681f3Smrgstatic inline nir_ssa_def *
9457ec681f3Smrgnir_udiv_imm(nir_builder *build, nir_ssa_def *x, uint64_t y)
9467ec681f3Smrg{
9477ec681f3Smrg   assert(x->bit_size <= 64);
9487ec681f3Smrg   y &= BITFIELD64_MASK(x->bit_size);
9497ec681f3Smrg
9507ec681f3Smrg   if (y == 1) {
9517ec681f3Smrg      return x;
9527ec681f3Smrg   } else if (util_is_power_of_two_nonzero(y)) {
9537ec681f3Smrg      return nir_ushr_imm(build, x, ffsll(y) - 1);
9547ec681f3Smrg   } else {
9557ec681f3Smrg      return nir_udiv(build, x, nir_imm_intN_t(build, y, x->bit_size));
9567ec681f3Smrg   }
9577ec681f3Smrg}
9587ec681f3Smrg
9597ec681f3Smrgstatic inline nir_ssa_def *
9607ec681f3Smrgnir_fclamp(nir_builder *b,
9617ec681f3Smrg           nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
9627ec681f3Smrg{
9637ec681f3Smrg   return nir_fmin(b, nir_fmax(b, x, min_val), max_val);
9647ec681f3Smrg}
9657ec681f3Smrg
9667ec681f3Smrgstatic inline nir_ssa_def *
9677ec681f3Smrgnir_iclamp(nir_builder *b,
9687ec681f3Smrg           nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
9697ec681f3Smrg{
9707ec681f3Smrg   return nir_imin(b, nir_imax(b, x, min_val), max_val);
9717ec681f3Smrg}
9727ec681f3Smrg
9737ec681f3Smrgstatic inline nir_ssa_def *
9747ec681f3Smrgnir_uclamp(nir_builder *b,
9757ec681f3Smrg           nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
9767ec681f3Smrg{
9777ec681f3Smrg   return nir_umin(b, nir_umax(b, x, min_val), max_val);
9787ec681f3Smrg}
9797ec681f3Smrg
9807ec681f3Smrgstatic inline nir_ssa_def *
9817ec681f3Smrgnir_ffma_imm12(nir_builder *build, nir_ssa_def *src0, double src1, double src2)
9827ec681f3Smrg{
9837ec681f3Smrg   if (build->shader->options->avoid_ternary_with_two_constants)
9847ec681f3Smrg      return nir_fadd_imm(build, nir_fmul_imm(build, src0, src1), src2);
9857ec681f3Smrg   else
9867ec681f3Smrg      return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size),
9877ec681f3Smrg                             nir_imm_floatN_t(build, src2, src0->bit_size));
9887ec681f3Smrg}
9897ec681f3Smrg
9907ec681f3Smrgstatic inline nir_ssa_def *
9917ec681f3Smrgnir_ffma_imm1(nir_builder *build, nir_ssa_def *src0, double src1, nir_ssa_def *src2)
9927ec681f3Smrg{
9937ec681f3Smrg   return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size), src2);
9947ec681f3Smrg}
9957ec681f3Smrg
9967ec681f3Smrgstatic inline nir_ssa_def *
9977ec681f3Smrgnir_ffma_imm2(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1, double src2)
9987ec681f3Smrg{
9997ec681f3Smrg   return nir_ffma(build, src0, src1, nir_imm_floatN_t(build, src2, src0->bit_size));
10007ec681f3Smrg}
10017ec681f3Smrg
10027ec681f3Smrgstatic inline nir_ssa_def *
10037ec681f3Smrgnir_a_minus_bc(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1,
10047ec681f3Smrg               nir_ssa_def *src2)
10057ec681f3Smrg{
10067ec681f3Smrg   return nir_ffma(build, nir_fneg(build, src1), src2, src0);
10077ec681f3Smrg}
10087ec681f3Smrg
10097e102996Smayastatic inline nir_ssa_def *
10107e102996Smayanir_pack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size)
10117e102996Smaya{
10127e102996Smaya   assert(src->num_components * src->bit_size == dest_bit_size);
10137e102996Smaya
10147e102996Smaya   switch (dest_bit_size) {
10157e102996Smaya   case 64:
10167e102996Smaya      switch (src->bit_size) {
10177e102996Smaya      case 32: return nir_pack_64_2x32(b, src);
10187e102996Smaya      case 16: return nir_pack_64_4x16(b, src);
10197e102996Smaya      default: break;
10207e102996Smaya      }
10217e102996Smaya      break;
10227e102996Smaya
10237e102996Smaya   case 32:
10247e102996Smaya      if (src->bit_size == 16)
10257e102996Smaya         return nir_pack_32_2x16(b, src);
10267e102996Smaya      break;
10277e102996Smaya
10287e102996Smaya   default:
10297e102996Smaya      break;
10307e102996Smaya   }
10317e102996Smaya
10327e102996Smaya   /* If we got here, we have no dedicated unpack opcode. */
10337e102996Smaya   nir_ssa_def *dest = nir_imm_intN_t(b, 0, dest_bit_size);
10347e102996Smaya   for (unsigned i = 0; i < src->num_components; i++) {
10357e102996Smaya      nir_ssa_def *val = nir_u2u(b, nir_channel(b, src, i), dest_bit_size);
10367e102996Smaya      val = nir_ishl(b, val, nir_imm_int(b, i * src->bit_size));
10377e102996Smaya      dest = nir_ior(b, dest, val);
10387e102996Smaya   }
10397e102996Smaya   return dest;
10407e102996Smaya}
10417e102996Smaya
10427e102996Smayastatic inline nir_ssa_def *
10437e102996Smayanir_unpack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size)
10447e102996Smaya{
10457e102996Smaya   assert(src->num_components == 1);
10467e102996Smaya   assert(src->bit_size > dest_bit_size);
10477e102996Smaya   const unsigned dest_num_components = src->bit_size / dest_bit_size;
10487e102996Smaya   assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS);
10497e102996Smaya
10507e102996Smaya   switch (src->bit_size) {
10517e102996Smaya   case 64:
10527e102996Smaya      switch (dest_bit_size) {
10537e102996Smaya      case 32: return nir_unpack_64_2x32(b, src);
10547e102996Smaya      case 16: return nir_unpack_64_4x16(b, src);
10557e102996Smaya      default: break;
10567e102996Smaya      }
10577e102996Smaya      break;
10587e102996Smaya
10597e102996Smaya   case 32:
10607e102996Smaya      if (dest_bit_size == 16)
10617e102996Smaya         return nir_unpack_32_2x16(b, src);
10627e102996Smaya      break;
10637e102996Smaya
10647e102996Smaya   default:
10657e102996Smaya      break;
10667e102996Smaya   }
10677e102996Smaya
10687e102996Smaya   /* If we got here, we have no dedicated unpack opcode. */
10697e102996Smaya   nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS];
10707e102996Smaya   for (unsigned i = 0; i < dest_num_components; i++) {
10717ec681f3Smrg      nir_ssa_def *val = nir_ushr_imm(b, src, i * dest_bit_size);
10727e102996Smaya      dest_comps[i] = nir_u2u(b, val, dest_bit_size);
10737e102996Smaya   }
10747e102996Smaya   return nir_vec(b, dest_comps, dest_num_components);
10757e102996Smaya}
10767e102996Smaya
10777ec681f3Smrg/**
10787ec681f3Smrg * Treats srcs as if it's one big blob of bits and extracts the range of bits
10797ec681f3Smrg * given by
10807ec681f3Smrg *
10817ec681f3Smrg *       [first_bit, first_bit + dest_num_components * dest_bit_size)
10827ec681f3Smrg *
10837ec681f3Smrg * The range can have any alignment or size as long as it's an integer number
10847ec681f3Smrg * of destination components and fits inside the concatenated sources.
10857ec681f3Smrg *
10867ec681f3Smrg * TODO: The one caveat here is that we can't handle byte alignment if 64-bit
10877ec681f3Smrg * values are involved because that would require pack/unpack to/from a vec8
10887ec681f3Smrg * which NIR currently does not support.
10897ec681f3Smrg */
10907ec681f3Smrgstatic inline nir_ssa_def *
10917ec681f3Smrgnir_extract_bits(nir_builder *b, nir_ssa_def **srcs, unsigned num_srcs,
10927ec681f3Smrg                 unsigned first_bit,
10937ec681f3Smrg                 unsigned dest_num_components, unsigned dest_bit_size)
10947ec681f3Smrg{
10957ec681f3Smrg   const unsigned num_bits = dest_num_components * dest_bit_size;
10967ec681f3Smrg
10977ec681f3Smrg   /* Figure out the common bit size */
10987ec681f3Smrg   unsigned common_bit_size = dest_bit_size;
10997ec681f3Smrg   for (unsigned i = 0; i < num_srcs; i++)
11007ec681f3Smrg      common_bit_size = MIN2(common_bit_size, srcs[i]->bit_size);
11017ec681f3Smrg   if (first_bit > 0)
11027ec681f3Smrg      common_bit_size = MIN2(common_bit_size, (1u << (ffs(first_bit) - 1)));
11037ec681f3Smrg
11047ec681f3Smrg   /* We don't want to have to deal with 1-bit values */
11057ec681f3Smrg   assert(common_bit_size >= 8);
11067ec681f3Smrg
11077ec681f3Smrg   nir_ssa_def *common_comps[NIR_MAX_VEC_COMPONENTS * sizeof(uint64_t)];
11087ec681f3Smrg   assert(num_bits / common_bit_size <= ARRAY_SIZE(common_comps));
11097ec681f3Smrg
11107ec681f3Smrg   /* First, unpack to the common bit size and select the components from the
11117ec681f3Smrg    * source.
11127ec681f3Smrg    */
11137ec681f3Smrg   int src_idx = -1;
11147ec681f3Smrg   unsigned src_start_bit = 0;
11157ec681f3Smrg   unsigned src_end_bit = 0;
11167ec681f3Smrg   for (unsigned i = 0; i < num_bits / common_bit_size; i++) {
11177ec681f3Smrg      const unsigned bit = first_bit + (i * common_bit_size);
11187ec681f3Smrg      while (bit >= src_end_bit) {
11197ec681f3Smrg         src_idx++;
11207ec681f3Smrg         assert(src_idx < (int) num_srcs);
11217ec681f3Smrg         src_start_bit = src_end_bit;
11227ec681f3Smrg         src_end_bit += srcs[src_idx]->bit_size *
11237ec681f3Smrg                        srcs[src_idx]->num_components;
11247ec681f3Smrg      }
11257ec681f3Smrg      assert(bit >= src_start_bit);
11267ec681f3Smrg      assert(bit + common_bit_size <= src_end_bit);
11277ec681f3Smrg      const unsigned rel_bit = bit - src_start_bit;
11287ec681f3Smrg      const unsigned src_bit_size = srcs[src_idx]->bit_size;
11297ec681f3Smrg
11307ec681f3Smrg      nir_ssa_def *comp = nir_channel(b, srcs[src_idx],
11317ec681f3Smrg                                      rel_bit / src_bit_size);
11327ec681f3Smrg      if (srcs[src_idx]->bit_size > common_bit_size) {
11337ec681f3Smrg         nir_ssa_def *unpacked = nir_unpack_bits(b, comp, common_bit_size);
11347ec681f3Smrg         comp = nir_channel(b, unpacked, (rel_bit % src_bit_size) /
11357ec681f3Smrg                                         common_bit_size);
11367ec681f3Smrg      }
11377ec681f3Smrg      common_comps[i] = comp;
11387ec681f3Smrg   }
11397ec681f3Smrg
11407ec681f3Smrg   /* Now, re-pack the destination if we have to */
11417ec681f3Smrg   if (dest_bit_size > common_bit_size) {
11427ec681f3Smrg      unsigned common_per_dest = dest_bit_size / common_bit_size;
11437ec681f3Smrg      nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS];
11447ec681f3Smrg      for (unsigned i = 0; i < dest_num_components; i++) {
11457ec681f3Smrg         nir_ssa_def *unpacked = nir_vec(b, common_comps + i * common_per_dest,
11467ec681f3Smrg                                         common_per_dest);
11477ec681f3Smrg         dest_comps[i] = nir_pack_bits(b, unpacked, dest_bit_size);
11487ec681f3Smrg      }
11497ec681f3Smrg      return nir_vec(b, dest_comps, dest_num_components);
11507ec681f3Smrg   } else {
11517ec681f3Smrg      assert(dest_bit_size == common_bit_size);
11527ec681f3Smrg      return nir_vec(b, common_comps, dest_num_components);
11537ec681f3Smrg   }
11547ec681f3Smrg}
11557ec681f3Smrg
11567e102996Smayastatic inline nir_ssa_def *
11577e102996Smayanir_bitcast_vector(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size)
11587e102996Smaya{
11597e102996Smaya   assert((src->bit_size * src->num_components) % dest_bit_size == 0);
11607e102996Smaya   const unsigned dest_num_components =
11617e102996Smaya      (src->bit_size * src->num_components) / dest_bit_size;
11627e102996Smaya   assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS);
11637e102996Smaya
11647ec681f3Smrg   return nir_extract_bits(b, &src, 1, 0, dest_num_components, dest_bit_size);
11657ec681f3Smrg}
11667ec681f3Smrg
11677ec681f3Smrg/**
11687ec681f3Smrg * Pad a value to N components with undefs of matching bit size.
11697ec681f3Smrg * If the value already contains >= num_components, it is returned without change.
11707ec681f3Smrg */
11717ec681f3Smrgstatic inline nir_ssa_def *
11727ec681f3Smrgnir_pad_vector(nir_builder *b, nir_ssa_def *src, unsigned num_components)
11737ec681f3Smrg{
11747ec681f3Smrg   assert(src->num_components <= num_components);
11757ec681f3Smrg   if (src->num_components == num_components)
11767e102996Smaya      return src;
11777ec681f3Smrg
11787ec681f3Smrg   nir_ssa_def *components[NIR_MAX_VEC_COMPONENTS];
11797ec681f3Smrg   nir_ssa_def *undef = nir_ssa_undef(b, 1, src->bit_size);
11807ec681f3Smrg   unsigned i = 0;
11817ec681f3Smrg   for (; i < src->num_components; i++)
11827ec681f3Smrg      components[i] = nir_channel(b, src, i);
11837ec681f3Smrg   for (; i < num_components; i++)
11847ec681f3Smrg      components[i] = undef;
11857ec681f3Smrg
11867ec681f3Smrg   return nir_vec(b, components, num_components);
11877ec681f3Smrg}
11887ec681f3Smrg
11897ec681f3Smrg/**
11907ec681f3Smrg * Pad a value to N components with copies of the given immediate of matching
11917ec681f3Smrg * bit size. If the value already contains >= num_components, it is returned
11927ec681f3Smrg * without change.
11937ec681f3Smrg */
11947ec681f3Smrgstatic inline nir_ssa_def *
11957ec681f3Smrgnir_pad_vector_imm_int(nir_builder *b, nir_ssa_def *src, uint64_t imm_val,
11967ec681f3Smrg                       unsigned num_components)
11977ec681f3Smrg{
11987ec681f3Smrg   assert(src->num_components <= num_components);
11997ec681f3Smrg   if (src->num_components == num_components)
12007ec681f3Smrg      return src;
12017ec681f3Smrg
12027ec681f3Smrg   nir_ssa_def *components[NIR_MAX_VEC_COMPONENTS];
12037ec681f3Smrg   nir_ssa_def *imm = nir_imm_intN_t(b, imm_val, src->bit_size);
12047ec681f3Smrg   unsigned i = 0;
12057ec681f3Smrg   for (; i < src->num_components; i++)
12067ec681f3Smrg      components[i] = nir_channel(b, src, i);
12077ec681f3Smrg   for (; i < num_components; i++)
12087ec681f3Smrg      components[i] = imm;
12097ec681f3Smrg
12107ec681f3Smrg   return nir_vec(b, components, num_components);
12117ec681f3Smrg}
12127ec681f3Smrg
12137ec681f3Smrg/**
12147ec681f3Smrg * Pad a value to 4 components with undefs of matching bit size.
12157ec681f3Smrg * If the value already contains >= 4 components, it is returned without change.
12167ec681f3Smrg */
12177ec681f3Smrgstatic inline nir_ssa_def *
12187ec681f3Smrgnir_pad_vec4(nir_builder *b, nir_ssa_def *src)
12197ec681f3Smrg{
12207ec681f3Smrg   return nir_pad_vector(b, src, 4);
12217e102996Smaya}
12227e102996Smaya
122301e04c3fSmrg/**
122401e04c3fSmrg * Turns a nir_src into a nir_ssa_def * so it can be passed to
122501e04c3fSmrg * nir_build_alu()-based builder calls.
122601e04c3fSmrg *
122701e04c3fSmrg * See nir_ssa_for_alu_src() for alu instructions.
122801e04c3fSmrg */
122901e04c3fSmrgstatic inline nir_ssa_def *
123001e04c3fSmrgnir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
123101e04c3fSmrg{
123201e04c3fSmrg   if (src.is_ssa && src.ssa->num_components == num_components)
123301e04c3fSmrg      return src.ssa;
123401e04c3fSmrg
12357ec681f3Smrg   assert((unsigned)num_components <= nir_src_num_components(src));
12367ec681f3Smrg
123701e04c3fSmrg   nir_alu_src alu = { NIR_SRC_INIT };
123801e04c3fSmrg   alu.src = src;
12397ec681f3Smrg   for (int j = 0; j < NIR_MAX_VEC_COMPONENTS; j++)
124001e04c3fSmrg      alu.swizzle[j] = j;
124101e04c3fSmrg
12427ec681f3Smrg   return nir_mov_alu(build, alu, num_components);
124301e04c3fSmrg}
124401e04c3fSmrg
124501e04c3fSmrg/**
124601e04c3fSmrg * Similar to nir_ssa_for_src(), but for alu srcs, respecting the
124701e04c3fSmrg * nir_alu_src's swizzle.
124801e04c3fSmrg */
124901e04c3fSmrgstatic inline nir_ssa_def *
125001e04c3fSmrgnir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn)
125101e04c3fSmrg{
12527ec681f3Smrg   if (nir_alu_src_is_trivial_ssa(instr, srcn))
12537ec681f3Smrg      return instr->src[srcn].src.ssa;
12547ec681f3Smrg
125501e04c3fSmrg   nir_alu_src *src = &instr->src[srcn];
125601e04c3fSmrg   unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn);
12577ec681f3Smrg   return nir_mov_alu(build, *src, num_components);
125801e04c3fSmrg}
125901e04c3fSmrg
12607e102996Smayastatic inline unsigned
12617ec681f3Smrgnir_get_ptr_bitsize(nir_shader *shader)
12627e102996Smaya{
12637ec681f3Smrg   if (shader->info.stage == MESA_SHADER_KERNEL)
12647ec681f3Smrg      return shader->info.cs.ptr_size;
12657e102996Smaya   return 32;
12667e102996Smaya}
12677e102996Smaya
126801e04c3fSmrgstatic inline nir_deref_instr *
126901e04c3fSmrgnir_build_deref_var(nir_builder *build, nir_variable *var)
127001e04c3fSmrg{
127101e04c3fSmrg   nir_deref_instr *deref =
127201e04c3fSmrg      nir_deref_instr_create(build->shader, nir_deref_type_var);
127301e04c3fSmrg
12747ec681f3Smrg   deref->modes = (nir_variable_mode)var->data.mode;
127501e04c3fSmrg   deref->type = var->type;
127601e04c3fSmrg   deref->var = var;
127701e04c3fSmrg
12787e102996Smaya   nir_ssa_dest_init(&deref->instr, &deref->dest, 1,
12797ec681f3Smrg                     nir_get_ptr_bitsize(build->shader), NULL);
128001e04c3fSmrg
128101e04c3fSmrg   nir_builder_instr_insert(build, &deref->instr);
128201e04c3fSmrg
128301e04c3fSmrg   return deref;
128401e04c3fSmrg}
128501e04c3fSmrg
128601e04c3fSmrgstatic inline nir_deref_instr *
128701e04c3fSmrgnir_build_deref_array(nir_builder *build, nir_deref_instr *parent,
128801e04c3fSmrg                      nir_ssa_def *index)
128901e04c3fSmrg{
129001e04c3fSmrg   assert(glsl_type_is_array(parent->type) ||
129101e04c3fSmrg          glsl_type_is_matrix(parent->type) ||
129201e04c3fSmrg          glsl_type_is_vector(parent->type));
129301e04c3fSmrg
12947e102996Smaya   assert(index->bit_size == parent->dest.ssa.bit_size);
12957e102996Smaya
129601e04c3fSmrg   nir_deref_instr *deref =
129701e04c3fSmrg      nir_deref_instr_create(build->shader, nir_deref_type_array);
129801e04c3fSmrg
12997ec681f3Smrg   deref->modes = parent->modes;
130001e04c3fSmrg   deref->type = glsl_get_array_element(parent->type);
130101e04c3fSmrg   deref->parent = nir_src_for_ssa(&parent->dest.ssa);
130201e04c3fSmrg   deref->arr.index = nir_src_for_ssa(index);
130301e04c3fSmrg
130401e04c3fSmrg   nir_ssa_dest_init(&deref->instr, &deref->dest,
130501e04c3fSmrg                     parent->dest.ssa.num_components,
130601e04c3fSmrg                     parent->dest.ssa.bit_size, NULL);
130701e04c3fSmrg
130801e04c3fSmrg   nir_builder_instr_insert(build, &deref->instr);
130901e04c3fSmrg
131001e04c3fSmrg   return deref;
131101e04c3fSmrg}
131201e04c3fSmrg
13137e102996Smayastatic inline nir_deref_instr *
13147e102996Smayanir_build_deref_array_imm(nir_builder *build, nir_deref_instr *parent,
13157e102996Smaya                          int64_t index)
13167e102996Smaya{
13177e102996Smaya   assert(parent->dest.is_ssa);
13187e102996Smaya   nir_ssa_def *idx_ssa = nir_imm_intN_t(build, index,
13197e102996Smaya                                         parent->dest.ssa.bit_size);
13207e102996Smaya
13217e102996Smaya   return nir_build_deref_array(build, parent, idx_ssa);
13227e102996Smaya}
13237e102996Smaya
13247e102996Smayastatic inline nir_deref_instr *
13257e102996Smayanir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent,
13267e102996Smaya                             nir_ssa_def *index)
13277e102996Smaya{
13287e102996Smaya   assert(parent->deref_type == nir_deref_type_array ||
13297e102996Smaya          parent->deref_type == nir_deref_type_ptr_as_array ||
13307e102996Smaya          parent->deref_type == nir_deref_type_cast);
13317e102996Smaya
13327e102996Smaya   assert(index->bit_size == parent->dest.ssa.bit_size);
13337e102996Smaya
13347e102996Smaya   nir_deref_instr *deref =
13357e102996Smaya      nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array);
13367e102996Smaya
13377ec681f3Smrg   deref->modes = parent->modes;
13387e102996Smaya   deref->type = parent->type;
13397e102996Smaya   deref->parent = nir_src_for_ssa(&parent->dest.ssa);
13407e102996Smaya   deref->arr.index = nir_src_for_ssa(index);
13417e102996Smaya
13427e102996Smaya   nir_ssa_dest_init(&deref->instr, &deref->dest,
13437e102996Smaya                     parent->dest.ssa.num_components,
13447e102996Smaya                     parent->dest.ssa.bit_size, NULL);
13457e102996Smaya
13467e102996Smaya   nir_builder_instr_insert(build, &deref->instr);
13477e102996Smaya
13487e102996Smaya   return deref;
13497e102996Smaya}
13507e102996Smaya
135101e04c3fSmrgstatic inline nir_deref_instr *
135201e04c3fSmrgnir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent)
135301e04c3fSmrg{
135401e04c3fSmrg   assert(glsl_type_is_array(parent->type) ||
135501e04c3fSmrg          glsl_type_is_matrix(parent->type));
135601e04c3fSmrg
135701e04c3fSmrg   nir_deref_instr *deref =
135801e04c3fSmrg      nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard);
135901e04c3fSmrg
13607ec681f3Smrg   deref->modes = parent->modes;
136101e04c3fSmrg   deref->type = glsl_get_array_element(parent->type);
136201e04c3fSmrg   deref->parent = nir_src_for_ssa(&parent->dest.ssa);
136301e04c3fSmrg
136401e04c3fSmrg   nir_ssa_dest_init(&deref->instr, &deref->dest,
136501e04c3fSmrg                     parent->dest.ssa.num_components,
136601e04c3fSmrg                     parent->dest.ssa.bit_size, NULL);
136701e04c3fSmrg
136801e04c3fSmrg   nir_builder_instr_insert(build, &deref->instr);
136901e04c3fSmrg
137001e04c3fSmrg   return deref;
137101e04c3fSmrg}
137201e04c3fSmrg
137301e04c3fSmrgstatic inline nir_deref_instr *
137401e04c3fSmrgnir_build_deref_struct(nir_builder *build, nir_deref_instr *parent,
137501e04c3fSmrg                       unsigned index)
137601e04c3fSmrg{
13777e102996Smaya   assert(glsl_type_is_struct_or_ifc(parent->type));
137801e04c3fSmrg
137901e04c3fSmrg   nir_deref_instr *deref =
138001e04c3fSmrg      nir_deref_instr_create(build->shader, nir_deref_type_struct);
138101e04c3fSmrg
13827ec681f3Smrg   deref->modes = parent->modes;
138301e04c3fSmrg   deref->type = glsl_get_struct_field(parent->type, index);
138401e04c3fSmrg   deref->parent = nir_src_for_ssa(&parent->dest.ssa);
138501e04c3fSmrg   deref->strct.index = index;
138601e04c3fSmrg
138701e04c3fSmrg   nir_ssa_dest_init(&deref->instr, &deref->dest,
138801e04c3fSmrg                     parent->dest.ssa.num_components,
138901e04c3fSmrg                     parent->dest.ssa.bit_size, NULL);
139001e04c3fSmrg
139101e04c3fSmrg   nir_builder_instr_insert(build, &deref->instr);
139201e04c3fSmrg
139301e04c3fSmrg   return deref;
139401e04c3fSmrg}
139501e04c3fSmrg
139601e04c3fSmrgstatic inline nir_deref_instr *
139701e04c3fSmrgnir_build_deref_cast(nir_builder *build, nir_ssa_def *parent,
13987ec681f3Smrg                     nir_variable_mode modes, const struct glsl_type *type,
13997e102996Smaya                     unsigned ptr_stride)
140001e04c3fSmrg{
140101e04c3fSmrg   nir_deref_instr *deref =
140201e04c3fSmrg      nir_deref_instr_create(build->shader, nir_deref_type_cast);
140301e04c3fSmrg
14047ec681f3Smrg   deref->modes = modes;
140501e04c3fSmrg   deref->type = type;
140601e04c3fSmrg   deref->parent = nir_src_for_ssa(parent);
14077e102996Smaya   deref->cast.ptr_stride = ptr_stride;
140801e04c3fSmrg
140901e04c3fSmrg   nir_ssa_dest_init(&deref->instr, &deref->dest,
141001e04c3fSmrg                     parent->num_components, parent->bit_size, NULL);
141101e04c3fSmrg
141201e04c3fSmrg   nir_builder_instr_insert(build, &deref->instr);
141301e04c3fSmrg
141401e04c3fSmrg   return deref;
141501e04c3fSmrg}
141601e04c3fSmrg
14177ec681f3Smrgstatic inline nir_deref_instr *
14187ec681f3Smrgnir_alignment_deref_cast(nir_builder *build, nir_deref_instr *parent,
14197ec681f3Smrg                         uint32_t align_mul, uint32_t align_offset)
14207ec681f3Smrg{
14217ec681f3Smrg   nir_deref_instr *deref =
14227ec681f3Smrg      nir_deref_instr_create(build->shader, nir_deref_type_cast);
14237ec681f3Smrg
14247ec681f3Smrg   deref->modes = parent->modes;
14257ec681f3Smrg   deref->type = parent->type;
14267ec681f3Smrg   deref->parent = nir_src_for_ssa(&parent->dest.ssa);
14277ec681f3Smrg   deref->cast.ptr_stride = nir_deref_instr_array_stride(deref);
14287ec681f3Smrg   deref->cast.align_mul = align_mul;
14297ec681f3Smrg   deref->cast.align_offset = align_offset;
14307ec681f3Smrg
14317ec681f3Smrg   nir_ssa_dest_init(&deref->instr, &deref->dest,
14327ec681f3Smrg                     parent->dest.ssa.num_components,
14337ec681f3Smrg                     parent->dest.ssa.bit_size, NULL);
14347ec681f3Smrg
14357ec681f3Smrg   nir_builder_instr_insert(build, &deref->instr);
14367ec681f3Smrg
14377ec681f3Smrg   return deref;
14387ec681f3Smrg}
14397ec681f3Smrg
144001e04c3fSmrg/** Returns a deref that follows another but starting from the given parent
144101e04c3fSmrg *
144201e04c3fSmrg * The new deref will be the same type and take the same array or struct index
144301e04c3fSmrg * as the leader deref but it may have a different parent.  This is very
144401e04c3fSmrg * useful for walking deref paths.
144501e04c3fSmrg */
144601e04c3fSmrgstatic inline nir_deref_instr *
144701e04c3fSmrgnir_build_deref_follower(nir_builder *b, nir_deref_instr *parent,
144801e04c3fSmrg                         nir_deref_instr *leader)
144901e04c3fSmrg{
145001e04c3fSmrg   /* If the derefs would have the same parent, don't make a new one */
145101e04c3fSmrg   assert(leader->parent.is_ssa);
145201e04c3fSmrg   if (leader->parent.ssa == &parent->dest.ssa)
145301e04c3fSmrg      return leader;
145401e04c3fSmrg
145501e04c3fSmrg   UNUSED nir_deref_instr *leader_parent = nir_src_as_deref(leader->parent);
145601e04c3fSmrg
145701e04c3fSmrg   switch (leader->deref_type) {
145801e04c3fSmrg   case nir_deref_type_var:
145901e04c3fSmrg      unreachable("A var dereference cannot have a parent");
146001e04c3fSmrg      break;
146101e04c3fSmrg
146201e04c3fSmrg   case nir_deref_type_array:
146301e04c3fSmrg   case nir_deref_type_array_wildcard:
146401e04c3fSmrg      assert(glsl_type_is_matrix(parent->type) ||
14657e102996Smaya             glsl_type_is_array(parent->type) ||
14667e102996Smaya             (leader->deref_type == nir_deref_type_array &&
14677e102996Smaya              glsl_type_is_vector(parent->type)));
146801e04c3fSmrg      assert(glsl_get_length(parent->type) ==
146901e04c3fSmrg             glsl_get_length(leader_parent->type));
147001e04c3fSmrg
147101e04c3fSmrg      if (leader->deref_type == nir_deref_type_array) {
147201e04c3fSmrg         assert(leader->arr.index.is_ssa);
14737e102996Smaya         nir_ssa_def *index = nir_i2i(b, leader->arr.index.ssa,
14747e102996Smaya                                         parent->dest.ssa.bit_size);
14757e102996Smaya         return nir_build_deref_array(b, parent, index);
147601e04c3fSmrg      } else {
147701e04c3fSmrg         return nir_build_deref_array_wildcard(b, parent);
147801e04c3fSmrg      }
147901e04c3fSmrg
148001e04c3fSmrg   case nir_deref_type_struct:
14817e102996Smaya      assert(glsl_type_is_struct_or_ifc(parent->type));
148201e04c3fSmrg      assert(glsl_get_length(parent->type) ==
148301e04c3fSmrg             glsl_get_length(leader_parent->type));
148401e04c3fSmrg
148501e04c3fSmrg      return nir_build_deref_struct(b, parent, leader->strct.index);
148601e04c3fSmrg
148701e04c3fSmrg   default:
148801e04c3fSmrg      unreachable("Invalid deref instruction type");
148901e04c3fSmrg   }
149001e04c3fSmrg}
149101e04c3fSmrg
149201e04c3fSmrgstatic inline nir_ssa_def *
149301e04c3fSmrgnir_load_reg(nir_builder *build, nir_register *reg)
149401e04c3fSmrg{
149501e04c3fSmrg   return nir_ssa_for_src(build, nir_src_for_reg(reg), reg->num_components);
149601e04c3fSmrg}
149701e04c3fSmrg
14987ec681f3Smrgstatic inline void
14997ec681f3Smrgnir_store_reg(nir_builder *build, nir_register *reg,
15007ec681f3Smrg              nir_ssa_def *def, nir_component_mask_t write_mask)
15017ec681f3Smrg{
15027ec681f3Smrg   assert(reg->num_components == def->num_components);
15037ec681f3Smrg   assert(reg->bit_size == def->bit_size);
15047ec681f3Smrg
15057ec681f3Smrg   nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov);
15067ec681f3Smrg   mov->src[0].src = nir_src_for_ssa(def);
15077ec681f3Smrg   mov->dest.dest = nir_dest_for_reg(reg);
15087ec681f3Smrg   mov->dest.write_mask = write_mask & BITFIELD_MASK(reg->num_components);
15097ec681f3Smrg   nir_builder_instr_insert(build, &mov->instr);
15107ec681f3Smrg}
15117ec681f3Smrg
151201e04c3fSmrgstatic inline nir_ssa_def *
15137e102996Smayanir_load_deref_with_access(nir_builder *build, nir_deref_instr *deref,
15147e102996Smaya                           enum gl_access_qualifier access)
151501e04c3fSmrg{
15167ec681f3Smrg   return nir_build_load_deref(build, glsl_get_vector_elements(deref->type),
15177ec681f3Smrg                               glsl_get_bit_size(deref->type), &deref->dest.ssa,
15187ec681f3Smrg                               access);
151901e04c3fSmrg}
152001e04c3fSmrg
15217ec681f3Smrg#undef nir_load_deref
15227e102996Smayastatic inline nir_ssa_def *
15237e102996Smayanir_load_deref(nir_builder *build, nir_deref_instr *deref)
15247e102996Smaya{
15257e102996Smaya   return nir_load_deref_with_access(build, deref, (enum gl_access_qualifier)0);
15267e102996Smaya}
15277e102996Smaya
152801e04c3fSmrgstatic inline void
15297e102996Smayanir_store_deref_with_access(nir_builder *build, nir_deref_instr *deref,
15307e102996Smaya                            nir_ssa_def *value, unsigned writemask,
15317e102996Smaya                            enum gl_access_qualifier access)
153201e04c3fSmrg{
15337ec681f3Smrg   writemask &= (1u << value->num_components) - 1u;
15347ec681f3Smrg   nir_build_store_deref(build, &deref->dest.ssa, value, writemask, access);
153501e04c3fSmrg}
153601e04c3fSmrg
15377ec681f3Smrg#undef nir_store_deref
153801e04c3fSmrgstatic inline void
15397e102996Smayanir_store_deref(nir_builder *build, nir_deref_instr *deref,
15407e102996Smaya                nir_ssa_def *value, unsigned writemask)
15417e102996Smaya{
15427e102996Smaya   nir_store_deref_with_access(build, deref, value, writemask,
15437e102996Smaya                               (enum gl_access_qualifier)0);
15447e102996Smaya}
15457e102996Smaya
15467e102996Smayastatic inline void
15477e102996Smayanir_copy_deref_with_access(nir_builder *build, nir_deref_instr *dest,
15487e102996Smaya                           nir_deref_instr *src,
15497e102996Smaya                           enum gl_access_qualifier dest_access,
15507e102996Smaya                           enum gl_access_qualifier src_access)
155101e04c3fSmrg{
15527ec681f3Smrg   nir_build_copy_deref(build, &dest->dest.ssa, &src->dest.ssa, dest_access, src_access);
155301e04c3fSmrg}
155401e04c3fSmrg
15557ec681f3Smrg#undef nir_copy_deref
15567e102996Smayastatic inline void
15577e102996Smayanir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src)
15587e102996Smaya{
15597e102996Smaya   nir_copy_deref_with_access(build, dest, src,
15607e102996Smaya                              (enum gl_access_qualifier) 0,
15617e102996Smaya                              (enum gl_access_qualifier) 0);
15627e102996Smaya}
15637e102996Smaya
15647ec681f3Smrgstatic inline void
15657ec681f3Smrgnir_memcpy_deref_with_access(nir_builder *build, nir_deref_instr *dest,
15667ec681f3Smrg                             nir_deref_instr *src, nir_ssa_def *size,
15677ec681f3Smrg                             enum gl_access_qualifier dest_access,
15687ec681f3Smrg                             enum gl_access_qualifier src_access)
15697ec681f3Smrg{
15707ec681f3Smrg   nir_build_memcpy_deref(build, &dest->dest.ssa, &src->dest.ssa,
15717ec681f3Smrg                          size, dest_access, src_access);
15727ec681f3Smrg}
15737ec681f3Smrg
15747ec681f3Smrg#undef nir_memcpy_deref
15757ec681f3Smrgstatic inline void
15767ec681f3Smrgnir_memcpy_deref(nir_builder *build, nir_deref_instr *dest,
15777ec681f3Smrg                 nir_deref_instr *src, nir_ssa_def *size)
15787ec681f3Smrg{
15797ec681f3Smrg   nir_memcpy_deref_with_access(build, dest, src, size,
15807ec681f3Smrg                                (enum gl_access_qualifier)0,
15817ec681f3Smrg                                (enum gl_access_qualifier)0);
15827ec681f3Smrg}
15837ec681f3Smrg
158401e04c3fSmrgstatic inline nir_ssa_def *
158501e04c3fSmrgnir_load_var(nir_builder *build, nir_variable *var)
158601e04c3fSmrg{
158701e04c3fSmrg   return nir_load_deref(build, nir_build_deref_var(build, var));
158801e04c3fSmrg}
158901e04c3fSmrg
159001e04c3fSmrgstatic inline void
159101e04c3fSmrgnir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value,
159201e04c3fSmrg              unsigned writemask)
159301e04c3fSmrg{
159401e04c3fSmrg   nir_store_deref(build, nir_build_deref_var(build, var), value, writemask);
159501e04c3fSmrg}
159601e04c3fSmrg
159701e04c3fSmrgstatic inline void
159801e04c3fSmrgnir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src)
159901e04c3fSmrg{
160001e04c3fSmrg   nir_copy_deref(build, nir_build_deref_var(build, dest),
160101e04c3fSmrg                         nir_build_deref_var(build, src));
160201e04c3fSmrg}
160301e04c3fSmrg
16047ec681f3Smrg#undef nir_load_global
160501e04c3fSmrgstatic inline nir_ssa_def *
16067ec681f3Smrgnir_load_global(nir_builder *build, nir_ssa_def *addr, unsigned align,
16077ec681f3Smrg                unsigned num_components, unsigned bit_size)
160801e04c3fSmrg{
16097ec681f3Smrg   nir_intrinsic_instr *load =
16107ec681f3Smrg      nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global);
16117ec681f3Smrg   load->num_components = num_components;
16127ec681f3Smrg   load->src[0] = nir_src_for_ssa(addr);
16137ec681f3Smrg   nir_intrinsic_set_align(load, align, 0);
16147ec681f3Smrg   nir_ssa_dest_init(&load->instr, &load->dest,
16157ec681f3Smrg                     num_components, bit_size, NULL);
16167ec681f3Smrg   nir_builder_instr_insert(build, &load->instr);
16177ec681f3Smrg   return &load->dest.ssa;
16187ec681f3Smrg}
16197ec681f3Smrg
16207ec681f3Smrg#undef nir_store_global
16217ec681f3Smrgstatic inline void
16227ec681f3Smrgnir_store_global(nir_builder *build, nir_ssa_def *addr, unsigned align,
16237ec681f3Smrg                 nir_ssa_def *value, nir_component_mask_t write_mask)
16247ec681f3Smrg{
16257ec681f3Smrg   nir_intrinsic_instr *store =
16267ec681f3Smrg      nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_global);
16277ec681f3Smrg   store->num_components = value->num_components;
16287ec681f3Smrg   store->src[0] = nir_src_for_ssa(value);
16297ec681f3Smrg   store->src[1] = nir_src_for_ssa(addr);
16307ec681f3Smrg   nir_intrinsic_set_write_mask(store,
16317ec681f3Smrg      write_mask & BITFIELD_MASK(value->num_components));
16327ec681f3Smrg   nir_intrinsic_set_align(store, align, 0);
16337ec681f3Smrg   nir_builder_instr_insert(build, &store->instr);
16347ec681f3Smrg}
163501e04c3fSmrg
16367ec681f3Smrg#undef nir_load_global_constant
16377ec681f3Smrgstatic inline nir_ssa_def *
16387ec681f3Smrgnir_load_global_constant(nir_builder *build, nir_ssa_def *addr, unsigned align,
16397ec681f3Smrg                         unsigned num_components, unsigned bit_size)
16407ec681f3Smrg{
164101e04c3fSmrg   nir_intrinsic_instr *load =
16427ec681f3Smrg      nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global_constant);
16437ec681f3Smrg   load->num_components = num_components;
16447ec681f3Smrg   load->src[0] = nir_src_for_ssa(addr);
16457ec681f3Smrg   nir_intrinsic_set_align(load, align, 0);
164601e04c3fSmrg   nir_ssa_dest_init(&load->instr, &load->dest,
16477ec681f3Smrg                     num_components, bit_size, NULL);
164801e04c3fSmrg   nir_builder_instr_insert(build, &load->instr);
164901e04c3fSmrg   return &load->dest.ssa;
165001e04c3fSmrg}
165101e04c3fSmrg
16527ec681f3Smrg#undef nir_load_param
16537ec681f3Smrgstatic inline nir_ssa_def *
16547ec681f3Smrgnir_load_param(nir_builder *build, uint32_t param_idx)
16557ec681f3Smrg{
16567ec681f3Smrg   assert(param_idx < build->impl->function->num_params);
16577ec681f3Smrg   nir_parameter *param = &build->impl->function->params[param_idx];
16587ec681f3Smrg   return nir_build_load_param(build, param->num_components, param->bit_size, param_idx);
16597ec681f3Smrg}
16607ec681f3Smrg
16617ec681f3Smrg/**
16627ec681f3Smrg * This function takes an I/O intrinsic like load/store_input,
16637ec681f3Smrg * and emits a sequence that calculates the full offset of that instruction,
16647ec681f3Smrg * including a stride to the base and component offsets.
16657ec681f3Smrg */
16667ec681f3Smrgstatic inline nir_ssa_def *
16677ec681f3Smrgnir_build_calc_io_offset(nir_builder *b,
16687ec681f3Smrg                         nir_intrinsic_instr *intrin,
16697ec681f3Smrg                         nir_ssa_def *base_stride,
16707ec681f3Smrg                         unsigned component_stride)
16717ec681f3Smrg{
16727ec681f3Smrg   /* base is the driver_location, which is in slots (1 slot = 4x4 bytes) */
16737ec681f3Smrg   nir_ssa_def *base_op = nir_imul_imm(b, base_stride, nir_intrinsic_base(intrin));
16747ec681f3Smrg
16757ec681f3Smrg   /* offset should be interpreted in relation to the base,
16767ec681f3Smrg    * so the instruction effectively reads/writes another input/output
16777ec681f3Smrg    * when it has an offset
16787ec681f3Smrg    */
16797ec681f3Smrg   nir_ssa_def *offset_op = nir_imul(b, base_stride, nir_ssa_for_src(b, *nir_get_io_offset_src(intrin), 1));
16807ec681f3Smrg
16817ec681f3Smrg   /* component is in bytes */
16827ec681f3Smrg   unsigned const_op = nir_intrinsic_component(intrin) * component_stride;
16837ec681f3Smrg
16847ec681f3Smrg   return nir_iadd_imm_nuw(b, nir_iadd_nuw(b, base_op, offset_op), const_op);
16857ec681f3Smrg}
16867ec681f3Smrg
16877ec681f3Smrg/* calculate a `(1 << value) - 1` in ssa without overflows */
16887ec681f3Smrgstatic inline nir_ssa_def *
16897ec681f3Smrgnir_mask(nir_builder *b, nir_ssa_def *bits, unsigned dst_bit_size)
16907ec681f3Smrg{
16917ec681f3Smrg   return nir_ushr(b, nir_imm_intN_t(b, -1, dst_bit_size),
16927ec681f3Smrg                      nir_isub_imm(b, dst_bit_size, nir_u2u32(b, bits)));
16937ec681f3Smrg}
169401e04c3fSmrg
16957e102996Smayastatic inline nir_ssa_def *
16967e102996Smayanir_f2b(nir_builder *build, nir_ssa_def *f)
16977e102996Smaya{
16987e102996Smaya   return nir_f2b1(build, f);
16997e102996Smaya}
17007e102996Smaya
17017e102996Smayastatic inline nir_ssa_def *
17027e102996Smayanir_i2b(nir_builder *build, nir_ssa_def *i)
17037e102996Smaya{
17047e102996Smaya   return nir_i2b1(build, i);
17057e102996Smaya}
17067e102996Smaya
17077e102996Smayastatic inline nir_ssa_def *
17087e102996Smayanir_b2f(nir_builder *build, nir_ssa_def *b, uint32_t bit_size)
17097e102996Smaya{
17107e102996Smaya   switch (bit_size) {
17117e102996Smaya   case 64: return nir_b2f64(build, b);
17127e102996Smaya   case 32: return nir_b2f32(build, b);
17137e102996Smaya   case 16: return nir_b2f16(build, b);
17147e102996Smaya   default:
17157e102996Smaya      unreachable("Invalid bit-size");
17167e102996Smaya   };
17177e102996Smaya}
17187e102996Smaya
17197ec681f3Smrgstatic inline nir_ssa_def *
17207ec681f3Smrgnir_b2i(nir_builder *build, nir_ssa_def *b, uint32_t bit_size)
17217ec681f3Smrg{
17227ec681f3Smrg   switch (bit_size) {
17237ec681f3Smrg   case 64: return nir_b2i64(build, b);
17247ec681f3Smrg   case 32: return nir_b2i32(build, b);
17257ec681f3Smrg   case 16: return nir_b2i16(build, b);
17267ec681f3Smrg   case 8:  return nir_b2i8(build, b);
17277ec681f3Smrg   default:
17287ec681f3Smrg      unreachable("Invalid bit-size");
17297ec681f3Smrg   };
17307ec681f3Smrg}
173101e04c3fSmrgstatic inline nir_ssa_def *
173201e04c3fSmrgnir_load_barycentric(nir_builder *build, nir_intrinsic_op op,
173301e04c3fSmrg                     unsigned interp_mode)
173401e04c3fSmrg{
17357ec681f3Smrg   unsigned num_components = op == nir_intrinsic_load_barycentric_model ? 3 : 2;
173601e04c3fSmrg   nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op);
17377ec681f3Smrg   nir_ssa_dest_init(&bary->instr, &bary->dest, num_components, 32, NULL);
173801e04c3fSmrg   nir_intrinsic_set_interp_mode(bary, interp_mode);
173901e04c3fSmrg   nir_builder_instr_insert(build, &bary->instr);
174001e04c3fSmrg   return &bary->dest.ssa;
174101e04c3fSmrg}
174201e04c3fSmrg
174301e04c3fSmrgstatic inline void
174401e04c3fSmrgnir_jump(nir_builder *build, nir_jump_type jump_type)
174501e04c3fSmrg{
17467ec681f3Smrg   assert(jump_type != nir_jump_goto && jump_type != nir_jump_goto_if);
174701e04c3fSmrg   nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type);
174801e04c3fSmrg   nir_builder_instr_insert(build, &jump->instr);
174901e04c3fSmrg}
175001e04c3fSmrg
17517ec681f3Smrgstatic inline void
17527ec681f3Smrgnir_goto(nir_builder *build, struct nir_block *target)
17537ec681f3Smrg{
17547ec681f3Smrg   assert(!build->impl->structured);
17557ec681f3Smrg   nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto);
17567ec681f3Smrg   jump->target = target;
17577ec681f3Smrg   nir_builder_instr_insert(build, &jump->instr);
17587ec681f3Smrg}
17597ec681f3Smrg
17607ec681f3Smrgstatic inline void
17617ec681f3Smrgnir_goto_if(nir_builder *build, struct nir_block *target, nir_src cond,
17627ec681f3Smrg            struct nir_block *else_target)
17637ec681f3Smrg{
17647ec681f3Smrg   assert(!build->impl->structured);
17657ec681f3Smrg   nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto_if);
17667ec681f3Smrg   jump->condition = cond;
17677ec681f3Smrg   jump->target = target;
17687ec681f3Smrg   jump->else_target = else_target;
17697ec681f3Smrg   nir_builder_instr_insert(build, &jump->instr);
17707ec681f3Smrg}
17717ec681f3Smrg
177201e04c3fSmrgstatic inline nir_ssa_def *
177301e04c3fSmrgnir_compare_func(nir_builder *b, enum compare_func func,
177401e04c3fSmrg                 nir_ssa_def *src0, nir_ssa_def *src1)
177501e04c3fSmrg{
177601e04c3fSmrg   switch (func) {
177701e04c3fSmrg   case COMPARE_FUNC_NEVER:
177801e04c3fSmrg      return nir_imm_int(b, 0);
177901e04c3fSmrg   case COMPARE_FUNC_ALWAYS:
178001e04c3fSmrg      return nir_imm_int(b, ~0);
178101e04c3fSmrg   case COMPARE_FUNC_EQUAL:
178201e04c3fSmrg      return nir_feq(b, src0, src1);
178301e04c3fSmrg   case COMPARE_FUNC_NOTEQUAL:
17847ec681f3Smrg      return nir_fneu(b, src0, src1);
178501e04c3fSmrg   case COMPARE_FUNC_GREATER:
178601e04c3fSmrg      return nir_flt(b, src1, src0);
178701e04c3fSmrg   case COMPARE_FUNC_GEQUAL:
178801e04c3fSmrg      return nir_fge(b, src0, src1);
178901e04c3fSmrg   case COMPARE_FUNC_LESS:
179001e04c3fSmrg      return nir_flt(b, src0, src1);
179101e04c3fSmrg   case COMPARE_FUNC_LEQUAL:
179201e04c3fSmrg      return nir_fge(b, src1, src0);
179301e04c3fSmrg   }
179401e04c3fSmrg   unreachable("bad compare func");
179501e04c3fSmrg}
179601e04c3fSmrg
17977ec681f3Smrgstatic inline void
17987ec681f3Smrgnir_scoped_memory_barrier(nir_builder *b,
17997ec681f3Smrg                          nir_scope scope,
18007ec681f3Smrg                          nir_memory_semantics semantics,
18017ec681f3Smrg                          nir_variable_mode modes)
18027ec681f3Smrg{
18037ec681f3Smrg   nir_scoped_barrier(b, NIR_SCOPE_NONE, scope, semantics, modes);
18047ec681f3Smrg}
18057ec681f3Smrg
18067ec681f3Smrgstatic inline nir_ssa_def *
18077ec681f3Smrgnir_type_convert(nir_builder *b,
18087ec681f3Smrg                    nir_ssa_def *src,
18097ec681f3Smrg                    nir_alu_type src_type,
18107ec681f3Smrg                    nir_alu_type dest_type)
18117ec681f3Smrg{
18127ec681f3Smrg   assert(nir_alu_type_get_type_size(src_type) == 0 ||
18137ec681f3Smrg          nir_alu_type_get_type_size(src_type) == src->bit_size);
18147ec681f3Smrg
18157ec681f3Smrg   src_type = (nir_alu_type) (src_type | src->bit_size);
18167ec681f3Smrg
18177ec681f3Smrg   nir_op opcode =
18187ec681f3Smrg      nir_type_conversion_op(src_type, dest_type, nir_rounding_mode_undef);
18197ec681f3Smrg
18207ec681f3Smrg   return nir_build_alu(b, opcode, src, NULL, NULL, NULL);
18217ec681f3Smrg}
18227ec681f3Smrg
18237ec681f3Smrgstatic inline nir_ssa_def *
18247ec681f3Smrgnir_convert_to_bit_size(nir_builder *b,
18257ec681f3Smrg                    nir_ssa_def *src,
18267ec681f3Smrg                    nir_alu_type type,
18277ec681f3Smrg                    unsigned bit_size)
18287ec681f3Smrg{
18297ec681f3Smrg   return nir_type_convert(b, src, type, (nir_alu_type) (type | bit_size));
18307ec681f3Smrg}
18317ec681f3Smrg
18327ec681f3Smrgstatic inline nir_ssa_def *
18337ec681f3Smrgnir_i2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18347ec681f3Smrg{
18357ec681f3Smrg   return nir_convert_to_bit_size(b, src, nir_type_int, bit_size);
18367ec681f3Smrg}
18377ec681f3Smrg
18387ec681f3Smrgstatic inline nir_ssa_def *
18397ec681f3Smrgnir_u2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18407ec681f3Smrg{
18417ec681f3Smrg   return nir_convert_to_bit_size(b, src, nir_type_uint, bit_size);
18427ec681f3Smrg}
18437ec681f3Smrg
18447ec681f3Smrgstatic inline nir_ssa_def *
18457ec681f3Smrgnir_b2bN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18467ec681f3Smrg{
18477ec681f3Smrg   return nir_convert_to_bit_size(b, src, nir_type_bool, bit_size);
18487ec681f3Smrg}
18497ec681f3Smrg
18507ec681f3Smrgstatic inline nir_ssa_def *
18517ec681f3Smrgnir_f2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18527ec681f3Smrg{
18537ec681f3Smrg   return nir_convert_to_bit_size(b, src, nir_type_float, bit_size);
18547ec681f3Smrg}
18557ec681f3Smrg
18567ec681f3Smrgstatic inline nir_ssa_def *
18577ec681f3Smrgnir_i2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18587ec681f3Smrg{
18597ec681f3Smrg   return nir_type_convert(b, src, nir_type_int,
18607ec681f3Smrg         (nir_alu_type) (nir_type_float | bit_size));
18617ec681f3Smrg}
18627ec681f3Smrg
18637ec681f3Smrgstatic inline nir_ssa_def *
18647ec681f3Smrgnir_u2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18657ec681f3Smrg{
18667ec681f3Smrg   return nir_type_convert(b, src, nir_type_uint,
18677ec681f3Smrg         (nir_alu_type) (nir_type_float | bit_size));
18687ec681f3Smrg}
18697ec681f3Smrg
18707ec681f3Smrgstatic inline nir_ssa_def *
18717ec681f3Smrgnir_f2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18727ec681f3Smrg{
18737ec681f3Smrg   return nir_type_convert(b, src, nir_type_float,
18747ec681f3Smrg         (nir_alu_type) (nir_type_uint | bit_size));
18757ec681f3Smrg}
18767ec681f3Smrg
18777ec681f3Smrgstatic inline nir_ssa_def *
18787ec681f3Smrgnir_f2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size)
18797ec681f3Smrg{
18807ec681f3Smrg   return nir_type_convert(b, src, nir_type_float,
18817ec681f3Smrg         (nir_alu_type) (nir_type_int | bit_size));
18827ec681f3Smrg}
18837ec681f3Smrg
188401e04c3fSmrg#endif /* NIR_BUILDER_H */
1885