1b8e80941SmrgThis provides some background the design of the generated headers.  We
2b8e80941Smrgstarted out trying to generate bit fields but it evolved into the pack
3b8e80941Smrgfunctions because of a few limitations:
4b8e80941Smrg
5b8e80941Smrg  1) Bit fields still generate terrible code today. Even with modern
6b8e80941Smrg     optimizing compilers you get multiple load+mask+store operations
7b8e80941Smrg     to the same dword in memory as you set individual bits. The
8b8e80941Smrg     compiler also has to generate code to mask out overflowing values
9b8e80941Smrg     (for example, if you assign 200 to a 2 bit field). Our driver
10b8e80941Smrg     never writes overflowing values so that's not needed. On the
11b8e80941Smrg     other hand, most compiler recognize that the template struct we
12b8e80941Smrg     use is a temporary variable and copy propagate the individual
13b8e80941Smrg     fields and do amazing constant folding.  You should take a look
14b8e80941Smrg     at the code that gets generated when you compile in release mode
15b8e80941Smrg     with optimizations.
16b8e80941Smrg
17b8e80941Smrg  2) For some types we need to have overlapping bit fields. For
18b8e80941Smrg     example, some values are 64 byte aligned 32 bit offsets. The
19b8e80941Smrg     lower 5 bits of the offset are always zero, so the hw packs in a
20b8e80941Smrg     few misc bits in the lower 5 bits there. Other times a field can
21b8e80941Smrg     be either a u32 or a float. I tried to do this with overlapping
22b8e80941Smrg     anonymous unions and it became a big mess. Also, when using
23b8e80941Smrg     initializers, you can only initialize one union member so this
24b8e80941Smrg     just doesn't work with out approach.
25b8e80941Smrg
26b8e80941Smrg     The pack functions on the other hand allows us a great deal of
27b8e80941Smrg     flexibility in how we combine things. In the case of overlapping
28b8e80941Smrg     fields (the u32 and float case), if we only set one of them in
29b8e80941Smrg     the pack function, the compiler will recognize that the other is
30b8e80941Smrg     initialized to 0 and optimize out the code to or it it.
31b8e80941Smrg
32b8e80941Smrg  3) Bit fields (and certainly overlapping anonymous unions of bit
33b8e80941Smrg     fields) aren't generally stable across compilers in how they're
34b8e80941Smrg     laid out and aligned. Our pack functions let us control exactly
35b8e80941Smrg     how things get packed, using only simple and unambiguous bitwise
36b8e80941Smrg     shifting and or'ing that works on any compiler.
37b8e80941Smrg
38b8e80941SmrgOnce we have the pack function it allows us to hook in various
39b8e80941Smrgtransformations and validation as we go from template struct to dwords
40b8e80941Smrgin memory:
41b8e80941Smrg
42b8e80941Smrg  1) Validation: As I said above, our driver isn't supposed to write
43b8e80941Smrg     overflowing values to the fields, but we've of course had lots of
44b8e80941Smrg     cases where we make mistakes and write overflowing values. With
45b8e80941Smrg     the pack function, we can actually assert on that and catch it at
46b8e80941Smrg     runtime.  bitfields would just silently truncate.
47b8e80941Smrg
48b8e80941Smrg  2) Type conversions: some times it's just a matter of writing a
49b8e80941Smrg     float to a u32, but we also convert from bool to bits, from
50b8e80941Smrg     floats to fixed point integers.
51b8e80941Smrg
52b8e80941Smrg  3) Relocations: whenever we have a pointer from one buffer to
53b8e80941Smrg     another (for example a pointer from the meta data for a texture
54b8e80941Smrg     to the raw texture data), we have to tell the kernel about it so
55b8e80941Smrg     it can adjust the pointer to point to the final location. That
56b8e80941Smrg     means extra work we have to do extra work to record and annotate
57b8e80941Smrg     the dword location that holds the pointer. With bit fields, we'd
58b8e80941Smrg     have to call a function to do this, but with the pack function we
59b8e80941Smrg     generate code in the pack function to do this for us. That's a
60b8e80941Smrg     lot less error prone and less work.
61b8e80941Smrg
62b8e80941SmrgKeeping genxml files tidy :
63b8e80941Smrg
64b8e80941Smrg   In order to spot differences easily between generations, we keep genxml files sorted.
65b8e80941Smrg   You can trigger the sort by running :
66b8e80941Smrg
67b8e80941Smrg      $ cd src/intel/genxml; ./sort_xml.sh
68b8e80941Smrg
69b8e80941Smrg   gen_sort_tags.py is the script that sorts genxml files using with
70b8e80941Smrg   the following rules :
71b8e80941Smrg
72b8e80941Smrg      1) Tags are grouped in the following order <enum>, <struct>,
73b8e80941Smrg         <instruction>, <register>
74b8e80941Smrg
75b8e80941Smrg      2) <field> tags are sorted through the value of their start attribute
76b8e80941Smrg
77b8e80941Smrg      3) Sort <struct> tags by dependency so that other scripts have
78b8e80941Smrg         everything properly ordered.
79