else:
self.default = None
+ if "minus_one" in attrs:
+ assert(attrs["minus_one"] == "true")
+ self.minus_one = True
+ else:
+ self.minus_one = False
+
ufixed_match = Field.ufixed_pattern.match(self.type)
if ufixed_match:
self.type = 'ufixed'
relocs_emitted = set()
memcpy_fields = set()
+ for field in self.fields:
+ if field.minus_one:
+ print(" assert(values->%s >= 1);" % field.name)
+
for index in range(self.length):
# Handle MBZ bytes
if not index in bytes:
# uints/ints with no merged fields.
if len(byte.fields) == 1:
field = byte.fields[0]
- if field.type in ["float", "uint", "int"] and field.start % 8 == 0 and field.end - field.start == 31:
+ if field.type in ["float", "uint", "int"] and field.start % 8 == 0 and field.end - field.start == 31 and not field.minus_one:
if field in memcpy_fields:
continue
end -= field_byte_start
extra_shift = 0
+ value = "values->%s" % name
+ if field.minus_one:
+ value = "%s - 1" % value
+
if field.type == "mbo":
s = "__gen_mbo(%d, %d)" % \
(start, end)
extra_shift = (31 - (end - start)) // 8 * 8
s = "__gen_address_offset(&values->%s)" % byte.address.name
elif field.type == "uint":
- s = "__gen_uint(values->%s, %d, %d)" % \
- (name, start, end)
+ s = "__gen_uint(%s, %d, %d)" % \
+ (value, start, end)
elif field.type in self.parser.enums:
- s = "__gen_uint(values->%s, %d, %d)" % \
- (name, start, end)
+ s = "__gen_uint(%s, %d, %d)" % \
+ (value, start, end)
elif field.type == "int":
- s = "__gen_sint(values->%s, %d, %d)" % \
- (name, start, end)
+ s = "__gen_sint(%s, %d, %d)" % \
+ (value, start, end)
elif field.type == "bool":
- s = "__gen_uint(values->%s, %d, %d)" % \
- (name, start, end)
+ s = "__gen_uint(%s, %d, %d)" % \
+ (value, start, end)
elif field.type == "float":
s = "#error %s float value mixed in with other fields" % name
elif field.type == "offset":
- s = "__gen_offset(values->%s, %d, %d)" % \
- (name, start, end)
+ s = "__gen_offset(%s, %d, %d)" % \
+ (value, start, end)
elif field.type == 'ufixed':
- s = "__gen_ufixed(values->%s, %d, %d, %d)" % \
- (name, start, end, field.fractional_size)
+ s = "__gen_ufixed(%s, %d, %d, %d)" % \
+ (value, start, end, field.fractional_size)
elif field.type == 'sfixed':
- s = "__gen_sfixed(values->%s, %d, %d, %d)" % \
- (name, start, end, field.fractional_size)
+ s = "__gen_sfixed(%s, %d, %d, %d)" % \
+ (value, start, end, field.fractional_size)
elif field.type in self.parser.structs:
s = "__gen_uint(v%d_%d, %d, %d)" % \
(index, field_index, start, end)
print("/* unhandled field %s, type %s */\n" % (field.name, field.type))
s = None
- print(" values->%s = %s(%s);" % \
- (field.name, convert, ', '.join(args)))
+ plusone = ""
+ if field.minus_one:
+ plusone = " + 1"
+ print(" values->%s = %s(%s)%s;" % \
+ (field.name, convert, ', '.join(args), plusone))
class Value(object):
def __init__(self, attrs):
else if (strcmp(atts[i], "default") == 0) {
field->has_default = true;
field->default_value = strtoul(atts[i + 1], &p, 0);
+ } else if (strcmp(atts[i], "minus_one") == 0) {
+ assert(strcmp(atts[i + 1], "true") == 0);
+ field->minus_one = true;
}
}
int s = group_member_offset + iter->field->start;
int e = group_member_offset + iter->field->end;
+ assert(!iter->field->minus_one ||
+ iter->field->type.kind == V3D_TYPE_INT ||
+ iter->field->type.kind == V3D_TYPE_UINT);
+
switch (iter->field->type.kind) {
case V3D_TYPE_UNKNOWN:
case V3D_TYPE_INT: {
uint32_t value = __gen_unpack_sint(iter->p, s, e);
+ if (iter->field->minus_one)
+ value++;
snprintf(iter->value, sizeof(iter->value), "%d", value);
enum_name = v3d_get_enum_name(&iter->field->inline_enum, value);
break;
}
case V3D_TYPE_UINT: {
uint32_t value = __gen_unpack_uint(iter->p, s, e);
+ if (iter->field->minus_one)
+ value++;
snprintf(iter->value, sizeof(iter->value), "%u", value);
enum_name = v3d_get_enum_name(&iter->field->inline_enum, value);
break;