import re
import sys
import copy
+import textwrap
license = """/*
* Copyright (C) 2016 Intel Corporation
#ifndef __gen_field_functions
#define __gen_field_functions
+#ifdef NDEBUG
+#define NDEBUG_UNUSED __attribute__((unused))
+#else
+#define NDEBUG_UNUSED
+#endif
+
union __gen_value {
float f;
uint32_t dw;
}
static inline uint64_t
-__gen_uint(uint64_t v, uint32_t start, uint32_t end)
+__gen_uint(uint64_t v, uint32_t start, NDEBUG_UNUSED uint32_t end)
{
__gen_validate_value(v);
-#if DEBUG
+#ifndef NDEBUG
const int width = end - start + 1;
if (width < 64) {
const uint64_t max = (1ull << width) - 1;
__gen_validate_value(v);
-#if DEBUG
+#ifndef NDEBUG
if (width < 64) {
const int64_t max = (1ll << (width - 1)) - 1;
const int64_t min = -(1ll << (width - 1));
}
static inline uint64_t
-__gen_offset(uint64_t v, uint32_t start, uint32_t end)
+__gen_offset(uint64_t v, NDEBUG_UNUSED uint32_t start, NDEBUG_UNUSED uint32_t end)
{
__gen_validate_value(v);
-#if DEBUG
+#ifndef NDEBUG
uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
assert((v & ~mask) == 0);
const float factor = (1 << fract_bits);
-#if DEBUG
+#ifndef NDEBUG
const float max = ((1 << (end - start)) - 1) / factor;
const float min = -(1 << (end - start)) / factor;
assert(min <= v && v <= max);
}
static inline uint64_t
-__gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
+__gen_ufixed(float v, uint32_t start, NDEBUG_UNUSED uint32_t end, uint32_t fract_bits)
{
__gen_validate_value(v);
const float factor = (1 << fract_bits);
-#if DEBUG
+#ifndef NDEBUG
const float max = ((1 << (end - start + 1)) - 1) / factor;
const float min = 0.0f;
assert(min <= v && v <= max);
#error #define __gen_combine_address before including this file
#endif
+#undef NDEBUG_UNUSED
+
#endif
"""
self.type = 'sfixed'
self.fractional_size = int(sfixed_match.group(2))
+ def is_builtin_type(self):
+ builtins = [ 'address', 'bool', 'float', 'ufixed',
+ 'offset', 'sfixed', 'offset', 'int', 'uint', 'mbo' ]
+ return self.type in builtins
+
+ def is_struct_type(self):
+ return self.type in self.parser.structs
+
+ def is_enum_type(self):
+ return self.type in self.parser.enums
+
def emit_template_struct(self, dim):
if self.type == 'address':
type = '__gen_address_type'
type = 'int32_t'
elif self.type == 'uint':
type = 'uint32_t'
- elif self.type in self.parser.structs:
+ elif self.is_struct_type():
type = 'struct ' + self.parser.gen_prefix(safe_name(self.type))
- elif self.type in self.parser.enums:
+ elif self.is_enum_type():
type = 'enum ' + self.parser.gen_prefix(safe_name(self.type))
elif self.type == 'mbo':
return
else:
print("#error unhandled type: %s" % self.type)
+ return
print(" %-36s %s%s;" % (type, self.name, dim))
+ prefix = ""
if len(self.values) > 0 and self.default == None:
if self.prefix:
prefix = self.prefix + "_"
- else:
- prefix = ""
for value in self.values:
print("#define %-40s %d" % (prefix + value.name, value.value))
dwords[index + 1] = dwords[index]
index = index + 1
- def emit_pack_function(self, start):
+ def collect_dwords_and_length(self):
dwords = {}
self.collect_dwords(dwords, 0, "")
# index we've seen plus one.
if self.size > 0:
length = self.size // 32
- else:
+ elif dwords:
length = max(dwords.keys()) + 1
+ else:
+ length = 0
+ return (dwords, length)
+
+ def emit_pack_function(self, dwords, length):
for index in range(length):
# Handle MBZ dwords
if not index in dwords:
if len(dw.fields) == 1:
field = dw.fields[0]
name = field.name + field.dim
- if field.type in self.parser.structs and field.start % 32 == 0:
+ if field.is_struct_type() and field.start % 32 == 0:
print("")
print(" %s_pack(data, &dw[%d], &values->%s);" %
(self.parser.gen_prefix(safe_name(field.type)), index, name))
# to the dword for those fields.
field_index = 0
for field in dw.fields:
- if type(field) is Field and field.type in self.parser.structs:
+ if type(field) is Field and field.is_struct_type():
name = field.name + field.dim
print("")
print(" uint32_t v%d_%d;" % (index, field_index))
elif field.type == "uint":
non_address_fields.append("__gen_uint(values->%s, %d, %d)" % \
(name, field.start - dword_start, field.end - dword_start))
- elif field.type in self.parser.enums:
+ elif field.is_enum_type():
non_address_fields.append("__gen_uint(values->%s, %d, %d)" % \
(name, field.start - dword_start, field.end - dword_start))
elif field.type == "int":
elif field.type == 'sfixed':
non_address_fields.append("__gen_sfixed(values->%s, %d, %d, %d)" % \
(name, field.start - dword_start, field.end - dword_start, field.fractional_size))
- elif field.type in self.parser.structs:
+ elif field.is_struct_type():
non_address_fields.append("__gen_uint(v%d_%d, %d, %d)" % \
(index, field_index, field.start - dword_start, field.end - dword_start))
field_index = field_index + 1
if dw.size == 32:
if dw.address:
- print(" dw[%d] = __gen_combine_address(data, &dw[%d], values->%s, %s);" % (index, index, dw.address.name, v))
+ print(" dw[%d] = __gen_combine_address(data, &dw[%d], values->%s, %s);" % (index, index, dw.address.name + field.dim, v))
continue
if dw.address:
v_address = "v%d_address" % index
print(" const uint64_t %s =\n __gen_combine_address(data, &dw[%d], values->%s, %s);" %
- (v_address, index, dw.address.name, v))
+ (v_address, index, dw.address.name + field.dim, v))
v = v_address
print(" dw[%d] = %s;" % (index, v))
self.instruction = None
self.structs = {}
- self.enums = {}
+ # Set of enum names we've seen.
+ self.enums = set()
self.registers = {}
def gen_prefix(self, name):
elif name == "enum":
self.values = []
self.enum = safe_name(attrs["name"])
- self.enums[attrs["name"]] = 1
+ self.enums.add(attrs["name"])
if "prefix" in attrs:
self.prefix = safe_name(attrs["prefix"])
else:
def emit_pack_function(self, name, group):
name = self.gen_prefix(name)
- print("static inline void\n%s_pack(__gen_user_data *data, void * restrict dst,\n%sconst struct %s * restrict values)\n{" %
- (name, ' ' * (len(name) + 6), name))
-
- # Cast dst to make header C++ friendly
- print(" uint32_t * restrict dw = (uint32_t * restrict) dst;")
-
- group.emit_pack_function(0)
+ print(textwrap.dedent("""\
+ static inline void
+ %s_pack(__attribute__((unused)) __gen_user_data *data,
+ %s__attribute__((unused)) void * restrict dst,
+ %s__attribute__((unused)) const struct %s * restrict values)
+ {""") % (name, ' ' * len(name), ' ' * len(name), name))
+
+ (dwords, length) = group.collect_dwords_and_length()
+ if length:
+ # Cast dst to make header C++ friendly
+ print(" uint32_t * restrict dw = (uint32_t * restrict) dst;")
+
+ group.emit_pack_function(dwords, length)
print("}\n")