pan/genxml: Make sure we catch overflows on 32-bit integer fields

If we store the temporary value in a [u]int32_t, the result might be
silently truncated, making the overflow check in the u_pack helpers
useless.

Make sure we use 64-bit fields as soon as the size is greater than 31
bits to prevent that.

It forces us to fix some types in the xml and helper arguments (sint
wrongly defined as uint) and add explicit casts on u32 subtraction
whose result is stored in an s32.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35555>
This commit is contained in:
Boris Brezillon 2025-06-20 14:28:06 +02:00
parent 189bf9fe9a
commit 737fc5d3c1
9 changed files with 29 additions and 29 deletions

View file

@ -737,7 +737,7 @@ jm_emit_primitive(struct panfrost_batch *batch,
* on Valhall, so we don't need to set that here
*/
} else if (cfg.index_type) {
cfg.base_vertex_offset = draw->index_bias - ctx->offset_start;
cfg.base_vertex_offset = (int64_t)draw->index_bias - ctx->offset_start;
#if PAN_ARCH <= 7
cfg.indices = batch->indices;

View file

@ -1621,7 +1621,7 @@ cs_finish_fragment(struct cs_builder *b, bool increment_frag_completed,
static inline void
cs_add32(struct cs_builder *b, struct cs_index dest, struct cs_index src,
unsigned imm)
int32_t imm)
{
cs_emit(b, ADD_IMM32, I) {
I.destination = cs_dst32(b, dest);
@ -1632,7 +1632,7 @@ cs_add32(struct cs_builder *b, struct cs_index dest, struct cs_index src,
static inline void
cs_add64(struct cs_builder *b, struct cs_index dest, struct cs_index src,
unsigned imm)
int32_t imm)
{
cs_emit(b, ADD_IMM64, I) {
I.destination = cs_dst64(b, dest);

View file

@ -116,7 +116,7 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
case MALI_CS_OPCODE_MOVE32: {
cs_unpack(instr, CS_MOVE32, I);
fprintf(fp, "MOVE32 r%u, #0x%X", I.destination, I.immediate);
fprintf(fp, "MOVE32 r%u, #0x%" PRIX64, I.destination, I.immediate);
break;
}
@ -156,7 +156,7 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
cs_unpack(instr, CS_RUN_IDVS, I);
fprintf(
fp,
"RUN_IDVS%s%s%s.varying_srt%d.varying_fau%d.varying_tsd%d.frag_srt%d.frag_tsd%d r%u, #%x",
"RUN_IDVS%s%s%s.varying_srt%d.varying_fau%d.varying_tsd%d.frag_srt%d.frag_tsd%d r%u, #%" PRIx64,
I.progress_increment ? ".progress_inc" : "",
I.malloc_enable ? "" : ".no_malloc",
I.draw_id_register_enable ? ".draw_id_enable" : "",
@ -176,7 +176,7 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
".INVALID",
};
fprintf(fp, "RUN_IDVS2%s%s%s%s r%u, #%x",
fprintf(fp, "RUN_IDVS2%s%s%s%s r%u, #%" PRIx64,
I.progress_increment ? ".progress_inc" : "",
I.malloc_enable ? "" : ".no_malloc",
I.draw_id_register_enable ? ".draw_id_enable" : "",
@ -195,8 +195,8 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
"BFEXT_U32", "BFEXT_S32", "BFINS_IMM32", "UMIN_IMM32",
};
fprintf(fp, "%s r%u, r%u, #%d", instr_name[I.sub_opcode], I.destination,
I.source, I.immediate);
fprintf(fp, "%s r%u, r%u, #%" PRId64, instr_name[I.sub_opcode],
I.destination, I.source, I.immediate);
break;
}
@ -208,8 +208,8 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
"BFEXT_U64", "BFEXT_S64", "BFINS_IMM64", "UMIN_IMM64",
};
fprintf(fp, "%s d%u, d%u, #%d", instr_name[I.sub_opcode], I.destination,
I.source, I.immediate);
fprintf(fp, "%s d%u, d%u, #%" PRId64, instr_name[I.sub_opcode],
I.destination, I.source, I.immediate);
break;
}
@ -309,7 +309,7 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
const char *state =
I.state <= sizeof(state_name) ? state_name[I.state] : ".INVALID";
fprintf(fp, "SET_STATE_IMM32%s #%u", state, I.value);
fprintf(fp, "SET_STATE_IMM32%s #%" PRIu64, state, I.value);
break;
}
@ -364,7 +364,7 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
case MALI_CS_OPCODE_RUN_FULLSCREEN: {
cs_unpack(instr, CS_RUN_FULLSCREEN, I);
fprintf(fp, "RUN_FULLSCREEN%s r%u, #%x",
fprintf(fp, "RUN_FULLSCREEN%s r%u, #%" PRIx64,
I.progress_increment ? ".progress_inc" : "", I.dcd,
I.flags_override);
break;
@ -390,16 +390,16 @@ print_cs_instr(FILE *fp, const uint64_t *instr)
case MALI_CS_OPCODE_ADD_IMMEDIATE32: {
cs_unpack(instr, CS_ADD_IMM32, I);
fprintf(fp, "ADD_IMMEDIATE32 r%u, r%u, #%d", I.destination, I.source,
I.immediate);
fprintf(fp, "ADD_IMMEDIATE32 r%u, r%u, #%" PRId64, I.destination,
I.source, I.immediate);
break;
}
case MALI_CS_OPCODE_ADD_IMMEDIATE64: {
cs_unpack(instr, CS_ADD_IMM64, I);
fprintf(fp, "ADD_IMMEDIATE64 d%u, d%u, #%d", I.destination, I.source,
I.immediate);
fprintf(fp, "ADD_IMMEDIATE64 d%u, d%u, #%" PRId64, I.destination,
I.source, I.immediate);
break;
}

View file

@ -196,10 +196,10 @@ class Field(object):
type = 'bool'
elif self.type in ['float', 'ulod', 'slod']:
type = 'float'
elif self.type in ['uint', 'hex'] and self.end - self.start > 32:
elif self.type in ['uint', 'hex'] and self.end - self.start >= 31:
type = 'uint64_t'
elif self.type == 'int':
type = 'int32_t'
type = 'int64_t' if self.end - self.start >= 31 else 'int32_t'
elif self.type in ['uint', 'hex', 'uint/float', 'padded', 'Pixel Format', 'Component Swizzle']:
type = 'uint32_t'
elif self.type in self.parser.structs:
@ -488,12 +488,12 @@ class Group(object):
elif field.type in self.parser.enums:
print(' fprintf(fp, "%*s{}: %s\\n", indent, "", {}_as_str({}));'.format(name, enum_name(field.type), val))
elif field.type == "int":
print(' fprintf(fp, "%*s{}: %d\\n", indent, "", {});'.format(name, val))
print(' fprintf(fp, "%*s{}: %" PRId64 "\\n", indent, "", (int64_t){});'.format(name, val))
elif field.type == "bool":
print(' fprintf(fp, "%*s{}: %s\\n", indent, "", {} ? "true" : "false");'.format(name, val))
elif field.type in ["float", "ulod", "slod"]:
print(' fprintf(fp, "%*s{}: %f\\n", indent, "", {});'.format(name, val))
elif field.type in ["uint", "hex"] and (field.end - field.start) >= 32:
elif field.type in ["uint", "hex"] and (field.end - field.start) >= 31:
print(' fprintf(fp, "%*s{}: 0x%" PRIx64 "\\n", indent, "", {});'.format(name, val))
elif field.type == "hex":
print(' fprintf(fp, "%*s{}: 0x%x\\n", indent, "", {});'.format(name, val))

View file

@ -524,8 +524,8 @@
<field name="Clean Fragment Write" size="1" start="0:11" type="bool"/>
<field name="Instance Size" size="8" start="0:16" type="padded" default="1"/>
<field name="Instance Primitive Size" size="8" start="0:24" type="padded" default="1"/>
<field name="Offset start" size="32" start="1:0" type="uint"/>
<field name="Primitive Index Base" size="32" start="2:0" type="uint"/>
<field name="Offset start" size="32" start="1:0" type="int"/>
<field name="Primitive Index Base" size="32" start="2:0" type="int"/>
<field name="Position" size="64" start="4:0" type="address"/>
<field name="Uniform buffers" size="64" start="6:0" type="address"/>
<field name="Textures" size="64" start="8:0" type="address"/>

View file

@ -559,8 +559,8 @@
<field name="Clean Fragment Write" size="1" start="0:11" type="bool"/>
<field name="Instance Size" size="8" start="0:16" type="padded" default="1"/>
<field name="Instance Primitive Size" size="8" start="0:24" type="padded" default="1"/>
<field name="Offset start" size="32" start="1:0" type="uint"/>
<field name="Primitive Index Base" size="32" start="2:0" type="uint"/>
<field name="Offset start" size="32" start="1:0" type="int"/>
<field name="Primitive Index Base" size="32" start="2:0" type="int"/>
<field name="Position" size="64" start="4:0" type="address"/>
<field name="Uniform buffers" size="64" start="6:0" type="address"/>
<field name="Textures" size="64" start="8:0" type="address"/>

View file

@ -600,8 +600,8 @@
<field name="Clean Fragment Write" size="1" start="0:11" type="bool"/>
<field name="Instance Size" size="8" start="0:16" type="padded" default="1"/>
<field name="Instance Primitive Size" size="8" start="0:24" type="padded" default="1"/>
<field name="Offset start" size="32" start="1:0" type="uint"/>
<field name="Primitive Index Base" size="32" start="2:0" type="uint"/>
<field name="Offset start" size="32" start="1:0" type="int"/>
<field name="Primitive Index Base" size="32" start="2:0" type="int"/>
<field name="Position" size="64" start="4:0" type="address"/>
<field name="Uniform buffers" size="64" start="6:0" type="address"/>
<field name="Textures" size="64" start="8:0" type="address"/>

View file

@ -656,8 +656,8 @@
<field name="Clean Fragment Write" size="1" start="0:11" type="bool"/>
<field name="Instance Size" size="8" start="0:16" type="padded" default="1"/>
<field name="Instance Primitive Size" size="8" start="0:24" type="padded" default="1"/>
<field name="Offset start" size="32" start="1:0" type="uint"/>
<field name="Primitive Index Base" size="32" start="2:0" type="uint"/>
<field name="Offset start" size="32" start="1:0" type="int"/>
<field name="Primitive Index Base" size="32" start="2:0" type="int"/>
<field name="Position" size="64" start="4:0" type="address"/>
<field name="Uniform buffers" size="64" start="6:0" type="address"/>
<field name="Textures" size="64" start="8:0" type="address"/>

View file

@ -856,7 +856,7 @@ panvk_emit_tiler_primitive(struct panvk_cmd_buffer *cmdbuf,
cfg.index_count = draw->info.vertex.count;
cfg.indices = draw->indices;
cfg.base_vertex_offset =
draw->info.vertex.base - draw->info.vertex.raw_offset;
(int64_t)draw->info.vertex.base - draw->info.vertex.raw_offset;
switch (draw->info.index.size) {
case 4: