freedreno/ir3: array offset can be negative
It at least happens with some piglit tests, like
$piglit/bin/vp-address-01
VERT
DCL IN[0]
DCL IN[1]
DCL OUT[0], POSITION
DCL OUT[1], COLOR
DCL CONST[0..7]
DCL ADDR[0]
0: ARL ADDR[0].x, IN[1].xxxx
1: MOV_SAT OUT[1], CONST[ADDR[0].x-1]
2: DP4 OUT[0].x, CONST[4], IN[0]
3: DP4 OUT[0].y, CONST[5], IN[0]
4: DP4 OUT[0].z, CONST[6], IN[0]
5: DP4 OUT[0].w, CONST[7], IN[0]
6: END
Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
@@ -261,6 +261,7 @@ typedef union PACKED {
|
||||
/* to make compiler happy: */
|
||||
uint32_t dummy32;
|
||||
uint32_t dummy10 : 10;
|
||||
int32_t idummy10 : 10;
|
||||
uint32_t dummy11 : 11;
|
||||
uint32_t dummy12 : 12;
|
||||
uint32_t dummy13 : 13;
|
||||
|
||||
@@ -126,7 +126,7 @@ static uint32_t reg(struct ir3_register *reg, struct ir3_info *info,
|
||||
|
||||
if (reg->flags & IR3_REG_RELATIV) {
|
||||
components = reg->size;
|
||||
val.dummy10 = reg->array.offset;
|
||||
val.idummy10 = reg->array.offset;
|
||||
max = (reg->array.offset + repeat + components - 1) >> 2;
|
||||
} else {
|
||||
components = util_last_bit(reg->wrmask);
|
||||
|
||||
@@ -100,7 +100,7 @@ struct ir3_register {
|
||||
/* relative: */
|
||||
struct {
|
||||
uint16_t id;
|
||||
uint16_t offset;
|
||||
int16_t offset;
|
||||
} array;
|
||||
};
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@ create_uniform(struct ir3_compile *ctx, unsigned n)
|
||||
}
|
||||
|
||||
static struct ir3_instruction *
|
||||
create_uniform_indirect(struct ir3_compile *ctx, unsigned n,
|
||||
create_uniform_indirect(struct ir3_compile *ctx, int n,
|
||||
struct ir3_instruction *address)
|
||||
{
|
||||
struct ir3_instruction *mov;
|
||||
@@ -411,7 +411,7 @@ create_collect(struct ir3_block *block, struct ir3_instruction **arr,
|
||||
}
|
||||
|
||||
static struct ir3_instruction *
|
||||
create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
|
||||
create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, int n,
|
||||
struct ir3_instruction *address, struct ir3_instruction *collect)
|
||||
{
|
||||
struct ir3_block *block = ctx->block;
|
||||
@@ -434,7 +434,7 @@ create_indirect_load(struct ir3_compile *ctx, unsigned arrsz, unsigned n,
|
||||
|
||||
/* relative (indirect) if address!=NULL */
|
||||
static struct ir3_instruction *
|
||||
create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
|
||||
create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, int n,
|
||||
struct ir3_instruction *address)
|
||||
{
|
||||
struct ir3_block *block = ctx->block;
|
||||
@@ -462,7 +462,7 @@ create_var_load(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
|
||||
|
||||
/* relative (indirect) if address!=NULL */
|
||||
static struct ir3_instruction *
|
||||
create_var_store(struct ir3_compile *ctx, struct ir3_array *arr, unsigned n,
|
||||
create_var_store(struct ir3_compile *ctx, struct ir3_array *arr, int n,
|
||||
struct ir3_instruction *src, struct ir3_instruction *address)
|
||||
{
|
||||
struct ir3_block *block = ctx->block;
|
||||
@@ -1000,7 +1000,7 @@ emit_intrinsic_load_ubo(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
|
||||
nir_const_value *const_offset;
|
||||
/* UBO addresses are the first driver params: */
|
||||
unsigned ubo = regid(ctx->so->first_driver_param + IR3_UBOS_OFF, 0);
|
||||
unsigned off = intr->const_index[0];
|
||||
int off = intr->const_index[0];
|
||||
|
||||
/* First src is ubo index, which could either be an immed or not: */
|
||||
src0 = get_src(ctx, &intr->src[0])[0];
|
||||
@@ -1141,7 +1141,7 @@ emit_intrinsic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
|
||||
const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
|
||||
struct ir3_instruction **dst, **src;
|
||||
struct ir3_block *b = ctx->block;
|
||||
unsigned idx = intr->const_index[0];
|
||||
int idx = intr->const_index[0];
|
||||
nir_const_value *const_offset;
|
||||
|
||||
if (info->has_dest) {
|
||||
@@ -1162,7 +1162,7 @@ emit_intrinsic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
|
||||
} else {
|
||||
src = get_src(ctx, &intr->src[0]);
|
||||
for (int i = 0; i < intr->num_components; i++) {
|
||||
unsigned n = idx * 4 + i;
|
||||
int n = idx * 4 + i;
|
||||
dst[i] = create_uniform_indirect(ctx, n,
|
||||
get_addr(ctx, src[0]));
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ static void print_reg_name(struct ir3_register *reg)
|
||||
if (reg->flags & IR3_REG_IMMED) {
|
||||
printf("imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
|
||||
} else if (reg->flags & IR3_REG_ARRAY) {
|
||||
printf("arr[id=%u, offset=%u, size=%u", reg->array.id,
|
||||
printf("arr[id=%u, offset=%d, size=%u", reg->array.id,
|
||||
reg->array.offset, reg->size);
|
||||
/* for ARRAY we could have null src, for example first write
|
||||
* instruction..
|
||||
@@ -126,9 +126,9 @@ static void print_reg_name(struct ir3_register *reg)
|
||||
if (reg->flags & IR3_REG_HALF)
|
||||
printf("h");
|
||||
if (reg->flags & IR3_REG_CONST)
|
||||
printf("c<a0.x + %u>", reg->array.offset);
|
||||
printf("c<a0.x + %d>", reg->array.offset);
|
||||
else
|
||||
printf("\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->array.offset, reg->size);
|
||||
printf("\x1b[0;31mr<a0.x + %d>\x1b[0m (%u)", reg->array.offset, reg->size);
|
||||
} else {
|
||||
if (reg->flags & IR3_REG_HALF)
|
||||
printf("h");
|
||||
|
||||
Reference in New Issue
Block a user