+/**
+ * Read the current value of the ADDR register, convert the floats to
+ * ints, multiply by four and return the vector of offsets.
+ * The offsets will be used to index into the constant buffer or
+ * temporary register file.
+ */
+static LLVMValueRef
+get_indirect_index(struct lp_build_tgsi_soa_context *bld,
+ unsigned reg_file, unsigned reg_index,
+ const struct tgsi_src_register *indirect_reg)
+{
+ struct lp_build_context *uint_bld = &bld->uint_bld;
+ /* always use X component of address register */
+ unsigned swizzle = indirect_reg->SwizzleX;
+ LLVMValueRef base;
+ LLVMValueRef rel;
+ LLVMValueRef max_index;
+ LLVMValueRef index;
+
+ assert(bld->indirect_files & (1 << reg_file));
+
+ base = lp_build_const_int_vec(uint_bld->type, reg_index);
+
+ assert(swizzle < 4);
+ rel = LLVMBuildLoad(bld->base.builder,
+ bld->addr[indirect_reg->Index][swizzle],
+ "load addr reg");
+
+ /* for indexing we want integers */
+ rel = LLVMBuildFPToSI(bld->base.builder,
+ rel,
+ uint_bld->vec_type, "");
+
+ index = lp_build_add(uint_bld, base, rel);
+
+ max_index = lp_build_const_int_vec(uint_bld->type,
+ bld->info->file_max[reg_file]);
+
+ assert(!uint_bld->type.sign);
+ index = lp_build_min(uint_bld, index, max_index);
+
+ return index;
+}
+
+