#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
-#include "util/u_simple_list.h"
#include "tgsi/tgsi_dump.h"
#define BLD_MAX_TEMPS 64
struct bld_value_stack *stack)
{
struct nv_basic_block *in;
- struct nv_value *vals[16], *val;
+ struct nv_value *vals[16] = { 0 };
+ struct nv_value *val;
struct nv_instruction *phi;
int i, j, n;
{
int i;
struct nv_instruction *nvi;
+ struct nv_value *val;
for (i = 0; i < 4; ++i) {
if (!bld->saved_addr[i][0])
}
i &= 3;
- bld->saved_addr[i][0] = bld_load_imm_u32(bld, id);
+ val = bld_imm_u32(bld, id);
+ if (indirect)
+ val = bld_insn_2(bld, NV_OP_ADD, indirect, val);
+ else
+ val = bld_insn_1(bld, NV_OP_MOV, val);
+
+ bld->saved_addr[i][0] = val;
bld->saved_addr[i][0]->reg.file = NV_FILE_ADDR;
bld->saved_addr[i][0]->reg.type = NV_TYPE_U16;
bld->saved_addr[i][1] = indirect;
while (nvi->opcode == NV_OP_ABS || nvi->opcode == NV_OP_NEG ||
nvi->opcode == NV_OP_CVT) {
s0i = nvi->src[0]->value->insn;
- if (!s0i ||
- s0i->opcode == NV_OP_LDA ||
- s0i->opcode == NV_OP_MOV ||
- s0i->opcode == NV_OP_PHI)
+ if (!s0i || !nv50_op_can_write_flags(s0i->opcode))
break;
nvi = s0i;
assert(!nvi->flags_src);
}
}
- if (nvi->opcode == NV_OP_LDA ||
- nvi->opcode == NV_OP_MOV ||
- nvi->opcode == NV_OP_PHI || nvi->bb != bld->pc->current_block) {
+ if (!nv50_op_can_write_flags(nvi->opcode) ||
+ nvi->bb != bld->pc->current_block) {
nvi = new_instruction(bld->pc, NV_OP_CVT);
nv_reference(bld->pc, &nvi->src[0], src);
}
const struct tgsi_full_src_register *src = &insn->Src[s];
struct nv_value *res;
struct nv_value *ptr = NULL;
- unsigned idx, swz, dim_idx, ind_idx, ind_swz;
+ unsigned idx, swz, dim_idx, ind_idx, ind_swz, sgn;
ubyte type = infer_src_type(insn->Instruction.Opcode);
idx = src->Register.Index;
if (!res)
return bld_undef(bld, NV_FILE_GPR);
+ sgn = tgsi_util_get_full_src_register_sign_mode(src, chan);
+
if (insn->Instruction.Opcode != TGSI_OPCODE_MOV)
res->reg.as_type = type;
+ else
+ if (sgn != TGSI_UTIL_SIGN_KEEP) /* apparently "MOV A, -B" assumes float */
+ res->reg.as_type = NV_TYPE_F32;
- switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) {
+ switch (sgn) {
case TGSI_UTIL_SIGN_KEEP:
break;
case TGSI_UTIL_SIGN_CLEAR:
bld_lit(struct bld_context *bld, struct nv_value *dst0[4],
const struct tgsi_full_instruction *insn)
{
- struct nv_value *val0, *zero;
+ struct nv_value *val0 = NULL;
+ struct nv_value *zero = NULL;
unsigned mask = insn->Dst[0].Register.WriteMask;
if (mask & ((1 << 0) | (1 << 3)))
static void
load_proj_tex_coords(struct bld_context *bld,
- struct nv_value *t[4], int dim,
+ struct nv_value *t[4], int dim, int arg,
const struct tgsi_full_instruction *insn)
{
- int c, mask = 0;
+ int c, mask;
+
+ mask = (1 << dim) - 1;
+ if (arg != dim)
+ mask |= 4; /* depth comparison value */
t[3] = emit_fetch(bld, insn, 0, 3);
t[3] = bld_insn_1(bld, NV_OP_RCP, t[3]);
- for (c = 0; c < dim; ++c) {
+ for (c = 0; c < 4; ++c) {
+ if (!(mask & (1 << c)))
+ continue;
t[c] = emit_fetch(bld, insn, 0, c);
- if (t[c]->insn->opcode == NV_OP_LINTERP ||
- t[c]->insn->opcode == NV_OP_PINTERP) {
- t[c] = bld_duplicate_insn(bld, t[c]->insn);
- t[c]->insn->opcode = NV_OP_PINTERP;
- nv_reference(bld->pc, &t[c]->insn->src[1], t[3]);
- } else {
- mask |= 1 << c;
- }
+ if (t[c]->insn->opcode != NV_OP_LINTERP &&
+ t[c]->insn->opcode != NV_OP_PINTERP)
+ continue;
+ t[c] = bld_duplicate_insn(bld, t[c]->insn);
+ t[c]->insn->opcode = NV_OP_PINTERP;
+ nv_reference(bld->pc, &t[c]->insn->src[1], t[3]);
+
+ mask &= ~(1 << c);
}
for (c = 0; mask; ++c, mask >>= 1) {
get_tex_dim(insn, &dim, &arg);
if (!cube && insn->Instruction.Opcode == TGSI_OPCODE_TXP)
- load_proj_tex_coords(bld, t, dim, insn);
- else
+ load_proj_tex_coords(bld, t, dim, arg, insn);
+ else {
for (c = 0; c < dim; ++c)
t[c] = emit_fetch(bld, insn, 0, c);
+ if (arg != dim)
+ t[dim] = emit_fetch(bld, insn, 0, 2);
+ }
if (cube) {
assert(dim >= 3);
t[c] = bld_insn_2(bld, NV_OP_MUL, t[c], s[0]);
}
- if (arg != dim)
- t[dim] = emit_fetch(bld, insn, 0, 2);
-
if (opcode == NV_OP_TXB || opcode == NV_OP_TXL) {
t[arg++] = emit_fetch(bld, insn, 0, 3);
struct nv_value *src0;
struct nv_value *src1;
struct nv_value *src2;
- struct nv_value *dst0[4];
+ struct nv_value *dst0[4] = { 0 };
struct nv_value *temp;
int c;
uint opcode = translate_opcode(insn->Instruction.Opcode);