summary refs log tree commit diff
path: root/bit_field
diff options
context:
space:
mode:
authorJingkui Wang <jkwang@google.com>2018-05-22 11:22:13 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-03 22:14:45 -0700
commit8cad751ce00da86fcfd6bce1f71ba53ee8bf2051 (patch)
tree185c40263e30705c446f2ddb2d33fc67862f87f0 /bit_field
parentf11e6ed8e8664ae16a7e67b7a09eb00f3db24fa9 (diff)
downloadcrosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar.gz
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar.bz2
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar.lz
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar.xz
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.tar.zst
crosvm-8cad751ce00da86fcfd6bce1f71ba53ee8bf2051.zip
crosvm: Add bit_field_derive
Support macro derive(BitField) to make life easier.

BUG=None.
TEST=local build and run test.

Change-Id: I582620de250017fb7c0b601f9ad4fbcbbc2fe02a
Reviewed-on: https://chromium-review.googlesource.com/1069331
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Jingkui Wang <jkwang@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'bit_field')
-rw-r--r--bit_field/Cargo.toml7
-rw-r--r--bit_field/bit_field_derive/Cargo.toml13
-rw-r--r--bit_field/bit_field_derive/bit_field_derive.rs507
-rw-r--r--bit_field/src/lib.rs501
4 files changed, 1028 insertions, 0 deletions
diff --git a/bit_field/Cargo.toml b/bit_field/Cargo.toml
new file mode 100644
index 0000000..fe87900
--- /dev/null
+++ b/bit_field/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "bit_field"
+version = "0.1.0"
+authors = ["The Chromium OS Authors"]
+
+[dependencies]
+bit_field_derive = { path = "bit_field_derive" }
diff --git a/bit_field/bit_field_derive/Cargo.toml b/bit_field/bit_field_derive/Cargo.toml
new file mode 100644
index 0000000..4d11d2b
--- /dev/null
+++ b/bit_field/bit_field_derive/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "bit_field_derive"
+version = "0.1.0"
+authors = ["The Chromium OS Authors"]
+
+[dependencies]
+syn = "=0.12"
+quote = "=0.4"
+proc-macro2 = "=0.2"
+
+[lib]
+proc-macro = true
+path = "bit_field_derive.rs"
diff --git a/bit_field/bit_field_derive/bit_field_derive.rs b/bit_field/bit_field_derive/bit_field_derive.rs
new file mode 100644
index 0000000..1f2290d
--- /dev/null
+++ b/bit_field/bit_field_derive/bit_field_derive.rs
@@ -0,0 +1,507 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#![recursion_limit = "256"]
+extern crate proc_macro;
+extern crate proc_macro2;
+
+#[macro_use]
+extern crate quote;
+
+#[cfg_attr(test, macro_use)]
+extern crate syn;
+
+use std::string::String;
+use std::vec::Vec;
+
+use proc_macro::TokenStream;
+use proc_macro2::{Span, TokenNode};
+use quote::Tokens;
+use syn::{Attribute, Data, DeriveInput, Fields, Ident};
+
+type Result<T> = std::result::Result<T, String>;
+
+/// The function that derives the actual implementation.
+#[proc_macro_derive(BitField, attributes(passthrough))]
+pub fn bitfield(input: TokenStream) -> TokenStream {
+    bitfield_impl(syn::parse(input).unwrap()).into()
+}
+
+fn bitfield_impl(ast: DeriveInput) -> Tokens {
+    if !ast.generics.params.is_empty() {
+        return quote! {
+            compile_error!("derive(BitField) does not support generic parameters");
+        };
+    }
+
+    let name = ast.ident.to_string();
+    let struct_name = match get_struct_name(name.as_str()) {
+        Some(name) => name,
+        None => {
+            return quote! {
+                compile_error!("Check schema name, it should end with Schema.");
+            };
+        }
+    };
+
+    let ident = Ident::new(struct_name, Span::call_site());
+    let test_mod_ident = Ident::new(format!("test_{}", struct_name).as_str(), Span::call_site());
+    // Name of the struct
+    let name = quote!(#ident);
+    let vis = ast.vis.clone();
+    let attrs = match get_attrs(ast.attrs.as_slice()) {
+        Ok(attrs) => attrs,
+        Err(err_str) => {
+            return quote! {
+                compile_error!(#err_str);
+            };
+        }
+    };
+    // Visibility.
+    let vis = quote!(#vis);
+    let fields = match get_struct_fields(ast) {
+        Ok(f) => f,
+        Err(err_str) => {
+            return quote! {
+                compile_error!(#err_str);
+            }
+        }
+    };
+    let struct_def = get_struct_def(&vis, &name, fields.as_slice());
+    let bits_impl = get_bits_impl(&name);
+    let fields_impl = get_fields_impl(fields.as_slice());
+    let tests_impl = get_tests_impl(&name, fields.as_slice());
+    quote!(
+        #(#attrs)*
+        #struct_def
+        #bits_impl
+        impl #name {
+            #(#fields_impl)*
+        }
+        #[cfg(test)]
+        mod #test_mod_ident {
+            use super::*;
+            #(#tests_impl)*
+        }
+        )
+}
+
+// Generate struct name from schema_name. "MyTypeSchema" -> "MyType".
+fn get_struct_name(schema_name: &str) -> Option<&str> {
+    let struct_name = schema_name.trim_right_matches("Schema");
+    if struct_name.len() + "Schema".len() != schema_name.len() {
+        return None;
+    }
+    if struct_name.len() == 0 {
+        return None;
+    }
+    Some(struct_name)
+}
+
+// Unwrap ast to get the named fields. Anything unexpected will be treated as an
+// error.
+// We only care about field names and types.
+// "myfield : BitField3" -> ("myfield", Token(BitField3))
+fn get_struct_fields(ast: DeriveInput) -> Result<Vec<(String, Tokens)>> {
+    let fields = match ast.data {
+        Data::Struct(data_struct) => match data_struct.fields {
+            Fields::Named(fields_named) => fields_named.named,
+            _ => {
+                return Err(format!("Schema must have named fields."));
+            }
+        },
+        _ => {
+            return Err(format!("Schema must be a struct."));
+        }
+    };
+    let mut vec = Vec::new();
+    for field in fields {
+        let ident = match field.ident {
+            Some(ident) => ident,
+            None => {
+                return Err(format!(
+                    "Unknown Error. bit_field_derive library might have a bug."
+                ))
+            }
+        };
+        let ty = field.ty;
+        vec.push((ident.to_string(), quote!(#ty)));
+    }
+
+    Ok(vec)
+}
+
+// We only support attributes of the form #[passthrough(derive(Clone))].
+// Any other attribute will cause undefined behavior.
+fn get_attrs(attrs: &[Attribute]) -> Result<Vec<Tokens>> {
+    let mut attr_tokens = Vec::new();
+    for a in attrs {
+        let tts = a.tts.clone();
+        for t in tts {
+            match t.kind {
+                TokenNode::Group(_d, g) => attr_tokens.push(quote!(#[#g])),
+                _ => return Err(format!("Unsupported attribute.")),
+            }
+        }
+    }
+    Ok(attr_tokens)
+}
+
+fn get_struct_def(vis: &Tokens, name: &Tokens, fields: &[(String, Tokens)]) -> Tokens {
+    let mut field_types = Vec::new();
+    for &(ref _name, ref ty) in fields {
+        field_types.push(ty.clone());
+    }
+
+    // It will be something like:
+    // "(BitField1::FIELD_WIDTH + BitField3::FIELD_WIDTH + BitField4::FIELD_WIDTH) / 8)"
+    let data_size_in_bytes = quote!(
+            ( #( #field_types::FIELD_WIDTH as usize )+* ) / 8
+        );
+    quote! (
+        #vis struct #name {
+            data: [u8; #data_size_in_bytes],
+        }
+        impl #name {
+            pub fn new() -> #name {
+                #name { data: [0; #data_size_in_bytes], }
+            }
+        }
+    )
+}
+
+// Implement setter and getter for all fields.
+fn get_fields_impl(fields: &[(String, Tokens)]) -> Vec<Tokens> {
+    let mut impls = Vec::new();
+    // This vec keeps track of types before this field, used to generate the offset.
+    let mut current_types = vec![quote!(BitField0)];
+
+    for &(ref name, ref ty) in fields {
+        // Creating two copies of current types. As they are going to be moved in quote!.
+        let ct0 = current_types.clone();
+        let ct1 = current_types.clone();
+        let getter_ident = Ident::new(format!("get_{}", name).as_str(), Span::call_site());
+        let setter_ident = Ident::new(format!("set_{}", name).as_str(), Span::call_site());
+        impls.push(quote!(
+                pub fn #getter_ident(&self) -> <#ty as BitFieldSpecifier>::DefaultFieldType {
+                    let offset = #(#ct0::FIELD_WIDTH as usize)+*;
+                    return self.get(offset, #ty::FIELD_WIDTH) as
+                        <#ty as BitFieldSpecifier>::DefaultFieldType;
+                }
+
+                pub fn #setter_ident(&mut self, val: <#ty as BitFieldSpecifier>::DefaultFieldType) {
+                    debug_assert!((val as u64) <= #ty::FIELD_MAX);
+                    let offset = #(#ct1::FIELD_WIDTH as usize)+*;
+                    return self.set(offset, #ty::FIELD_WIDTH, val as u64);
+                }
+                ));
+        current_types.push(ty.clone());
+    }
+    impls
+}
+
+fn get_tests_impl(struct_name: &Tokens, fields: &[(String, Tokens)]) -> Vec<Tokens> {
+    let mut field_types = Vec::new();
+    for &(ref _name, ref ty) in fields {
+        field_types.push(ty.clone());
+    }
+    let field_types2 = field_types.clone();
+    let mut impls = Vec::new();
+    impls.push(quote!(
+                #[test]
+                fn test_total_size() {
+                    let total_size = #(#field_types::FIELD_WIDTH as usize)+*;
+                    assert_eq!(total_size % 8, 0);
+                }));
+    impls.push(quote!(#[test]
+    fn test_bits_boundary() {
+        let fields_sizes = vec![#(#field_types2::FIELD_WIDTH as usize),*];
+        let mut sum = 0usize;
+        for s in fields_sizes {
+            if sum % 64 == 0 {
+                assert!(s <= 64);
+            } else {
+                if (sum + s) % 64 != 0 {
+                    assert_eq!(sum / 64, (sum + s) / 64);
+                }
+            }
+            sum += s;
+        }
+    }));
+
+    for &(ref name, ref ty) in fields {
+        let testname = Ident::new(
+            format!("test_{}", name.as_str()).as_str(),
+            Span::call_site(),
+        );
+        let getter_ident = Ident::new(format!("get_{}", name.as_str()).as_str(), Span::call_site());
+        let setter_ident = Ident::new(format!("set_{}", name.as_str()).as_str(), Span::call_site());
+        impls.push(quote!(
+                #[test]
+                fn #testname() {
+                    let mut a = #struct_name::new();
+                    assert_eq!(a.#getter_ident() as u64, 0);
+                    a.#setter_ident(#ty::FIELD_MAX as <#ty as BitFieldSpecifier>::DefaultFieldType);
+                    assert_eq!(a.#getter_ident() as u64, #ty::FIELD_MAX);
+                }
+                ));
+    }
+    impls
+}
+
+fn get_bits_impl(name: &Tokens) -> Tokens {
+    quote!(
+        impl #name {
+            #[inline]
+            fn check_access(&self, offset: usize, width: u8) {
+                debug_assert!(width <= 64);
+                debug_assert!(offset / 8 < self.data.len());
+                debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
+            }
+
+
+            #[inline]
+            pub fn get_bit(&self, offset: usize) -> bool {
+                self.check_access(offset, 1);
+
+                let byte_index = offset / 8;
+                let bit_offset = offset % 8;
+
+                let byte = self.data[byte_index];
+                let mask = 1 << bit_offset;
+
+                byte & mask == mask
+            }
+
+            #[inline]
+            pub fn set_bit(&mut self, offset: usize, val: bool) {
+                self.check_access(offset, 1);
+
+                let byte_index = offset / 8;
+                let bit_offset = offset % 8;
+
+                let byte = &mut self.data[byte_index];
+                let mask = 1 << bit_offset;
+
+                if val {
+                    *byte |= mask;
+                } else {
+                    *byte &= !mask;
+                }
+            }
+
+            #[inline]
+            pub fn get(&self, offset: usize, width: u8) -> u64 {
+                self.check_access(offset, width);
+                let mut val = 0;
+
+                for i in 0..(width as usize) {
+                    if self.get_bit(i + offset) {
+                        val |= 1 << i;
+                    }
+                }
+
+                val
+            }
+
+            #[inline]
+            pub fn set(&mut self, offset: usize, width: u8, val: u64) {
+                self.check_access(offset, width);
+
+                for i in 0..(width as usize) {
+                    let mask = 1 << i;
+                    let val_bit_is_set = val & mask == mask;
+                    self.set_bit(i + offset, val_bit_is_set);
+                }
+            }
+        }
+        )
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn struct_name_parsing_valid() {
+        assert_eq!(get_struct_name("MyBitFieldSchema"), Some("MyBitField"));
+    }
+
+    #[test]
+    fn struct_name_parsing_invalid() {
+        assert_eq!(get_struct_name("MyBitFieldS"), None);
+    }
+
+    #[test]
+    fn end_to_end() {
+        let input: DeriveInput = parse_quote! {
+            #[passthrough(derive(Clone))]
+            struct MyBitFieldSchema {
+                a: BitField1,
+                b: BitField2,
+                c: BitField5,
+            }
+        };
+
+        let expected = quote! {
+            #[derive(Clone)]
+            struct MyBitField {
+                data: [u8; (BitField1::FIELD_WIDTH as usize
+                    + BitField2::FIELD_WIDTH as usize
+                    + BitField5::FIELD_WIDTH as usize) / 8],
+            }
+            impl MyBitField {
+                pub fn new() -> MyBitField {
+                    MyBitField {
+                        data: [0; (BitField1::FIELD_WIDTH as usize
+                            + BitField2::FIELD_WIDTH as usize
+                            + BitField5::FIELD_WIDTH as usize) / 8],
+                    }
+                }
+            }
+            impl MyBitField {
+                #[inline]
+                fn check_access(&self, offset: usize, width: u8) {
+                    debug_assert!(width <= 64);
+                    debug_assert!(offset / 8 < self.data.len());
+                    debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
+                }
+                #[inline]
+                pub fn get_bit(&self, offset: usize) -> bool {
+                    self.check_access(offset, 1);
+                    let byte_index = offset / 8;
+                    let bit_offset = offset % 8;
+                    let byte = self.data[byte_index];
+                    let mask = 1 << bit_offset;
+                    byte & mask == mask
+                }
+                #[inline]
+                pub fn set_bit(&mut self, offset: usize, val: bool) {
+                    self.check_access(offset, 1);
+                    let byte_index = offset / 8;
+                    let bit_offset = offset % 8;
+                    let byte = &mut self.data[byte_index];
+                    let mask = 1 << bit_offset;
+                    if val {
+                        *byte |= mask;
+                    } else {
+                        *byte &= !mask;
+                    }
+                }
+                #[inline]
+                pub fn get(&self, offset: usize, width: u8) -> u64 {
+                    self.check_access(offset, width);
+                    let mut val = 0;
+                    for i in 0..(width as usize) {
+                        if self.get_bit(i + offset) {
+                            val |= 1 << i;
+                        }
+                    }
+                    val
+                }
+                #[inline]
+                pub fn set(&mut self, offset: usize, width: u8, val: u64) {
+                    self.check_access(offset, width);
+                    for i in 0..(width as usize) {
+                        let mask = 1 << i;
+                        let val_bit_is_set = val & mask == mask;
+                        self.set_bit(i + offset, val_bit_is_set);
+                    }
+                }
+            }
+            impl MyBitField {
+                pub fn get_a(&self) -> <BitField1 as BitFieldSpecifier>::DefaultFieldType {
+                    let offset = BitField0::FIELD_WIDTH as usize;
+                    return self.get(offset, BitField1::FIELD_WIDTH)
+                        as <BitField1 as BitFieldSpecifier>::DefaultFieldType;
+                }
+                pub fn set_a(&mut self, val: <BitField1 as BitFieldSpecifier>::DefaultFieldType) {
+                    debug_assert!((val as u64) <= BitField1::FIELD_MAX);
+                    let offset = BitField0::FIELD_WIDTH as usize;
+                    return self.set(offset, BitField1::FIELD_WIDTH, val as u64);
+                }
+                pub fn get_b(&self) -> <BitField2 as BitFieldSpecifier>::DefaultFieldType {
+                    let offset = BitField0::FIELD_WIDTH as usize + BitField1::FIELD_WIDTH as usize;
+                    return self.get(offset, BitField2::FIELD_WIDTH)
+                        as <BitField2 as BitFieldSpecifier>::DefaultFieldType;
+                }
+                pub fn set_b(&mut self, val: <BitField2 as BitFieldSpecifier>::DefaultFieldType) {
+                    debug_assert!((val as u64) <= BitField2::FIELD_MAX);
+                    let offset = BitField0::FIELD_WIDTH as usize + BitField1::FIELD_WIDTH as usize;
+                    return self.set(offset, BitField2::FIELD_WIDTH, val as u64);
+                }
+                pub fn get_c(&self) -> <BitField5 as BitFieldSpecifier>::DefaultFieldType {
+                    let offset = BitField0::FIELD_WIDTH as usize
+                        + BitField1::FIELD_WIDTH as usize
+                        + BitField2::FIELD_WIDTH as usize;
+                    return self.get(offset, BitField5::FIELD_WIDTH)
+                        as <BitField5 as BitFieldSpecifier>::DefaultFieldType;
+                }
+                pub fn set_c(&mut self, val: <BitField5 as BitFieldSpecifier>::DefaultFieldType) {
+                    debug_assert!((val as u64) <= BitField5::FIELD_MAX);
+                    let offset = BitField0::FIELD_WIDTH as usize
+                        + BitField1::FIELD_WIDTH as usize
+                        + BitField2::FIELD_WIDTH as usize;
+                    return self.set(offset, BitField5::FIELD_WIDTH, val as u64);
+                }
+            }
+            #[cfg(test)]
+            mod test_MyBitField {
+                use super::*;
+                #[test]
+                fn test_total_size() {
+                    let total_size = BitField1::FIELD_WIDTH as usize
+                        + BitField2::FIELD_WIDTH as usize
+                        + BitField5::FIELD_WIDTH as usize;
+                    assert_eq!(total_size % 8, 0);
+                }
+                #[test]
+                fn test_bits_boundary() {
+                    let fields_sizes = vec![
+                        BitField1::FIELD_WIDTH as usize,
+                        BitField2::FIELD_WIDTH as usize,
+                        BitField5::FIELD_WIDTH as usize
+                    ];
+                    let mut sum = 0usize;
+                    for s in fields_sizes {
+                        if sum % 64 == 0 {
+                            assert!(s <= 64);
+                        } else {
+                            if (sum + s) % 64 != 0 {
+                                assert_eq!(sum / 64, (sum + s) / 64);
+                            }
+                        }
+                        sum += s;
+                    }
+                }
+                #[test]
+                fn test_a() {
+                    let mut a = MyBitField::new();
+                    assert_eq!(a.get_a() as u64, 0);
+                    a.set_a(BitField1::FIELD_MAX as
+                            <BitField1 as BitFieldSpecifier>::DefaultFieldType);
+                    assert_eq!(a.get_a() as u64, BitField1::FIELD_MAX);
+                }
+                #[test]
+                fn test_b() {
+                    let mut a = MyBitField::new();
+                    assert_eq!(a.get_b() as u64, 0);
+                    a.set_b(BitField2::FIELD_MAX as
+                            <BitField2 as BitFieldSpecifier>::DefaultFieldType);
+                    assert_eq!(a.get_b() as u64, BitField2::FIELD_MAX);
+                }
+                #[test]
+                fn test_c() {
+                    let mut a = MyBitField::new();
+                    assert_eq!(a.get_c() as u64, 0);
+                    a.set_c(BitField5::FIELD_MAX as
+                            <BitField5 as BitFieldSpecifier>::DefaultFieldType);
+                    assert_eq!(a.get_c() as u64, BitField5::FIELD_MAX);
+                }
+            }
+        };
+
+        assert_eq!(bitfield_impl(input), expected);
+    }
+}
diff --git a/bit_field/src/lib.rs b/bit_field/src/lib.rs
new file mode 100644
index 0000000..23d902e
--- /dev/null
+++ b/bit_field/src/lib.rs
@@ -0,0 +1,501 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#[allow(unused_imports)]
+#[macro_use]
+extern crate bit_field_derive;
+
+pub use bit_field_derive::*;
+
+/// BitFieldSpecifier is a group of structs help defining bitfield. It should only
+/// be used with bit_field custom derive. (#[derive(BitField)]).
+/// Example:
+/// #[derive(BitField)]
+/// pub struct MyBitFieldSchema {
+///     field_a : BitField1,
+///     field_b : BitField3,
+///     field_c : BitField5,
+///     field_d : BitField32,
+/// }
+///
+/// bit_field_derive implementation will use the static informations associated
+/// with those tyes to generate a struct named MyBitField and getter/setter for
+/// all fields.
+/// An example getter/setter is:
+///     fn get_field_a(&self) -> u8
+///     fn set_field_a(&self, val: u8)
+/// For larger fields:
+///     fn get_field_d(&self) -> u32
+///     fn set_field_d(&self, val: u32)
+///
+/// You can also pass attributes to the defined bitfield structs. Simply do this:
+/// #[passthrough(derive(Clone))]
+/// Any attributes other than #[passthrough(*)] will cause undefined behavior.
+/// For more details, refer to bit_field_derive.
+pub trait BitFieldSpecifier {
+    /// Width of this field in bits.
+    const FIELD_WIDTH: u8;
+    /// Max value of this field.
+    const FIELD_MAX: u64;
+    /// Default data type of this field.
+    /// For any field, we use the closest u* type. e.g. FIELD_WIDTH <= 8 will
+    /// have defulat type of u8.
+    /// It's possible to write a custom specifier and use i8.
+    type DefaultFieldType;
+}
+
+pub struct BitField0;
+impl BitFieldSpecifier for BitField0 {
+    const FIELD_WIDTH: u8 = 0;
+    const FIELD_MAX: u64 = 0x0;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField1;
+impl BitFieldSpecifier for BitField1 {
+    const FIELD_WIDTH: u8 = 1;
+    const FIELD_MAX: u64 = 0x1;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField2;
+impl BitFieldSpecifier for BitField2 {
+    const FIELD_WIDTH: u8 = 2;
+    const FIELD_MAX: u64 = 0x3;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField3;
+impl BitFieldSpecifier for BitField3 {
+    const FIELD_WIDTH: u8 = 3;
+    const FIELD_MAX: u64 = 0x7;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField4;
+impl BitFieldSpecifier for BitField4 {
+    const FIELD_WIDTH: u8 = 4;
+    const FIELD_MAX: u64 = 0xf;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField5;
+impl BitFieldSpecifier for BitField5 {
+    const FIELD_WIDTH: u8 = 5;
+    const FIELD_MAX: u64 = 0x1f;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField6;
+impl BitFieldSpecifier for BitField6 {
+    const FIELD_WIDTH: u8 = 6;
+    const FIELD_MAX: u64 = 0x3f;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField7;
+impl BitFieldSpecifier for BitField7 {
+    const FIELD_WIDTH: u8 = 7;
+    const FIELD_MAX: u64 = 0x7f;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField8;
+impl BitFieldSpecifier for BitField8 {
+    const FIELD_WIDTH: u8 = 8;
+    const FIELD_MAX: u64 = 0xff;
+    type DefaultFieldType = u8;
+}
+
+pub struct BitField9;
+impl BitFieldSpecifier for BitField9 {
+    const FIELD_WIDTH: u8 = 9;
+    const FIELD_MAX: u64 = 0x1ff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField10;
+impl BitFieldSpecifier for BitField10 {
+    const FIELD_WIDTH: u8 = 10;
+    const FIELD_MAX: u64 = 0x3ff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField11;
+impl BitFieldSpecifier for BitField11 {
+    const FIELD_WIDTH: u8 = 11;
+    const FIELD_MAX: u64 = 0x7ff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField12;
+impl BitFieldSpecifier for BitField12 {
+    const FIELD_WIDTH: u8 = 12;
+    const FIELD_MAX: u64 = 0xfff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField13;
+impl BitFieldSpecifier for BitField13 {
+    const FIELD_WIDTH: u8 = 13;
+    const FIELD_MAX: u64 = 0x1fff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField14;
+impl BitFieldSpecifier for BitField14 {
+    const FIELD_WIDTH: u8 = 14;
+    const FIELD_MAX: u64 = 0x3fff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField15;
+impl BitFieldSpecifier for BitField15 {
+    const FIELD_WIDTH: u8 = 15;
+    const FIELD_MAX: u64 = 0x7fff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField16;
+impl BitFieldSpecifier for BitField16 {
+    const FIELD_WIDTH: u8 = 16;
+    const FIELD_MAX: u64 = 0xffff;
+    type DefaultFieldType = u16;
+}
+
+pub struct BitField17;
+impl BitFieldSpecifier for BitField17 {
+    const FIELD_WIDTH: u8 = 17;
+    const FIELD_MAX: u64 = 0x1ffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField18;
+impl BitFieldSpecifier for BitField18 {
+    const FIELD_WIDTH: u8 = 18;
+    const FIELD_MAX: u64 = 0x3ffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField19;
+impl BitFieldSpecifier for BitField19 {
+    const FIELD_WIDTH: u8 = 19;
+    const FIELD_MAX: u64 = 0x7ffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField20;
+impl BitFieldSpecifier for BitField20 {
+    const FIELD_WIDTH: u8 = 20;
+    const FIELD_MAX: u64 = 0xfffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField21;
+impl BitFieldSpecifier for BitField21 {
+    const FIELD_WIDTH: u8 = 21;
+    const FIELD_MAX: u64 = 0x1fffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField22;
+impl BitFieldSpecifier for BitField22 {
+    const FIELD_WIDTH: u8 = 22;
+    const FIELD_MAX: u64 = 0x3fffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField23;
+impl BitFieldSpecifier for BitField23 {
+    const FIELD_WIDTH: u8 = 23;
+    const FIELD_MAX: u64 = 0x7fffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField24;
+impl BitFieldSpecifier for BitField24 {
+    const FIELD_WIDTH: u8 = 24;
+    const FIELD_MAX: u64 = 0xffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField25;
+impl BitFieldSpecifier for BitField25 {
+    const FIELD_WIDTH: u8 = 25;
+    const FIELD_MAX: u64 = 0x1ffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField26;
+impl BitFieldSpecifier for BitField26 {
+    const FIELD_WIDTH: u8 = 26;
+    const FIELD_MAX: u64 = 0x3ffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField27;
+impl BitFieldSpecifier for BitField27 {
+    const FIELD_WIDTH: u8 = 27;
+    const FIELD_MAX: u64 = 0x7ffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField28;
+impl BitFieldSpecifier for BitField28 {
+    const FIELD_WIDTH: u8 = 28;
+    const FIELD_MAX: u64 = 0xfffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField29;
+impl BitFieldSpecifier for BitField29 {
+    const FIELD_WIDTH: u8 = 29;
+    const FIELD_MAX: u64 = 0x1fffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField30;
+impl BitFieldSpecifier for BitField30 {
+    const FIELD_WIDTH: u8 = 30;
+    const FIELD_MAX: u64 = 0x3fffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField31;
+impl BitFieldSpecifier for BitField31 {
+    const FIELD_WIDTH: u8 = 31;
+    const FIELD_MAX: u64 = 0x7fffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField32;
+impl BitFieldSpecifier for BitField32 {
+    const FIELD_WIDTH: u8 = 32;
+    const FIELD_MAX: u64 = 0xffffffff;
+    type DefaultFieldType = u32;
+}
+
+pub struct BitField33;
+impl BitFieldSpecifier for BitField33 {
+    const FIELD_WIDTH: u8 = 33;
+    const FIELD_MAX: u64 = 0x1ffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField34;
+impl BitFieldSpecifier for BitField34 {
+    const FIELD_WIDTH: u8 = 34;
+    const FIELD_MAX: u64 = 0x3ffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField35;
+impl BitFieldSpecifier for BitField35 {
+    const FIELD_WIDTH: u8 = 35;
+    const FIELD_MAX: u64 = 0x7ffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField36;
+impl BitFieldSpecifier for BitField36 {
+    const FIELD_WIDTH: u8 = 36;
+    const FIELD_MAX: u64 = 0xfffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField37;
+impl BitFieldSpecifier for BitField37 {
+    const FIELD_WIDTH: u8 = 37;
+    const FIELD_MAX: u64 = 0x1fffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField38;
+impl BitFieldSpecifier for BitField38 {
+    const FIELD_WIDTH: u8 = 38;
+    const FIELD_MAX: u64 = 0x3fffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField39;
+impl BitFieldSpecifier for BitField39 {
+    const FIELD_WIDTH: u8 = 39;
+    const FIELD_MAX: u64 = 0x7fffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField40;
+impl BitFieldSpecifier for BitField40 {
+    const FIELD_WIDTH: u8 = 40;
+    const FIELD_MAX: u64 = 0xffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField41;
+impl BitFieldSpecifier for BitField41 {
+    const FIELD_WIDTH: u8 = 41;
+    const FIELD_MAX: u64 = 0x1ffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField42;
+impl BitFieldSpecifier for BitField42 {
+    const FIELD_WIDTH: u8 = 42;
+    const FIELD_MAX: u64 = 0x3ffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField43;
+impl BitFieldSpecifier for BitField43 {
+    const FIELD_WIDTH: u8 = 43;
+    const FIELD_MAX: u64 = 0x7ffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField44;
+impl BitFieldSpecifier for BitField44 {
+    const FIELD_WIDTH: u8 = 44;
+    const FIELD_MAX: u64 = 0xfffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField45;
+impl BitFieldSpecifier for BitField45 {
+    const FIELD_WIDTH: u8 = 45;
+    const FIELD_MAX: u64 = 0x1fffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField46;
+impl BitFieldSpecifier for BitField46 {
+    const FIELD_WIDTH: u8 = 46;
+    const FIELD_MAX: u64 = 0x3fffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField47;
+impl BitFieldSpecifier for BitField47 {
+    const FIELD_WIDTH: u8 = 47;
+    const FIELD_MAX: u64 = 0x7fffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField48;
+impl BitFieldSpecifier for BitField48 {
+    const FIELD_WIDTH: u8 = 48;
+    const FIELD_MAX: u64 = 0xffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField49;
+impl BitFieldSpecifier for BitField49 {
+    const FIELD_WIDTH: u8 = 49;
+    const FIELD_MAX: u64 = 0x1ffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField50;
+impl BitFieldSpecifier for BitField50 {
+    const FIELD_WIDTH: u8 = 50;
+    const FIELD_MAX: u64 = 0x3ffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField51;
+impl BitFieldSpecifier for BitField51 {
+    const FIELD_WIDTH: u8 = 51;
+    const FIELD_MAX: u64 = 0x7ffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField52;
+impl BitFieldSpecifier for BitField52 {
+    const FIELD_WIDTH: u8 = 52;
+    const FIELD_MAX: u64 = 0xfffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField53;
+impl BitFieldSpecifier for BitField53 {
+    const FIELD_WIDTH: u8 = 53;
+    const FIELD_MAX: u64 = 0x1fffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField54;
+impl BitFieldSpecifier for BitField54 {
+    const FIELD_WIDTH: u8 = 54;
+    const FIELD_MAX: u64 = 0x3fffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField55;
+impl BitFieldSpecifier for BitField55 {
+    const FIELD_WIDTH: u8 = 55;
+    const FIELD_MAX: u64 = 0x7fffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField56;
+impl BitFieldSpecifier for BitField56 {
+    const FIELD_WIDTH: u8 = 56;
+    const FIELD_MAX: u64 = 0xffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField57;
+impl BitFieldSpecifier for BitField57 {
+    const FIELD_WIDTH: u8 = 57;
+    const FIELD_MAX: u64 = 0x1ffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField58;
+impl BitFieldSpecifier for BitField58 {
+    const FIELD_WIDTH: u8 = 58;
+    const FIELD_MAX: u64 = 0x3ffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField59;
+impl BitFieldSpecifier for BitField59 {
+    const FIELD_WIDTH: u8 = 59;
+    const FIELD_MAX: u64 = 0x7ffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField60;
+impl BitFieldSpecifier for BitField60 {
+    const FIELD_WIDTH: u8 = 60;
+    const FIELD_MAX: u64 = 0xfffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField61;
+impl BitFieldSpecifier for BitField61 {
+    const FIELD_WIDTH: u8 = 61;
+    const FIELD_MAX: u64 = 0x1fffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField62;
+impl BitFieldSpecifier for BitField62 {
+    const FIELD_WIDTH: u8 = 62;
+    const FIELD_MAX: u64 = 0x3fffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField63;
+impl BitFieldSpecifier for BitField63 {
+    const FIELD_WIDTH: u8 = 63;
+    const FIELD_MAX: u64 = 0x7fffffffffffffff;
+    type DefaultFieldType = u64;
+}
+
+pub struct BitField64;
+impl BitFieldSpecifier for BitField64 {
+    const FIELD_WIDTH: u8 = 64;
+    const FIELD_MAX: u64 = 0xffffffffffffffff;
+    type DefaultFieldType = u64;
+}