summary refs log tree commit diff
path: root/bit_field
diff options
context:
space:
mode:
authorJingkui Wang <jkwang@google.com>2018-12-01 18:55:52 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-19 01:12:51 -0800
commit13b8c090bb5431a30d0d226c5e480861426509a0 (patch)
treee740bbd59b3518fb67c94b7825164c157086cc8b /bit_field
parent1dda82e8b288f538145abe15fbd42606edfc5c2a (diff)
downloadcrosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar.gz
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar.bz2
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar.lz
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar.xz
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.tar.zst
crosvm-13b8c090bb5431a30d0d226c5e480861426509a0.zip
bitfield: update bitfield structs and support bool
BitFieldSpecifiers are now generated by macros.
Can use BitFieldBool to specify a bool field.

BUG=chromium:831850
TEST=local cargo build/test

Change-Id: Id6b4a773ab612cea39ba811c3ec1da212b618ba2
Reviewed-on: https://chromium-review.googlesource.com/1356912
Commit-Ready: David Tolnay <dtolnay@chromium.org>
Tested-by: David Tolnay <dtolnay@chromium.org>
Reviewed-by: David Tolnay <dtolnay@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'bit_field')
-rw-r--r--bit_field/bit_field_derive/bit_field_derive.rs88
-rw-r--r--bit_field/src/lib.rs517
2 files changed, 116 insertions, 489 deletions
diff --git a/bit_field/bit_field_derive/bit_field_derive.rs b/bit_field/bit_field_derive/bit_field_derive.rs
index 85c5ca9..0f563c4 100644
--- a/bit_field/bit_field_derive/bit_field_derive.rs
+++ b/bit_field/bit_field_derive/bit_field_derive.rs
@@ -153,14 +153,15 @@ fn get_fields_impl(fields: &[(String, TokenStream)]) -> Vec<TokenStream> {
         impls.push(quote! {
             pub fn #getter_ident(&self) -> <#ty as BitFieldSpecifier>::DefaultFieldType {
                 let offset = #(#ct0::FIELD_WIDTH as usize)+*;
-                self.get(offset, #ty::FIELD_WIDTH) as
-                    <#ty as BitFieldSpecifier>::DefaultFieldType
+                let val = self.get(offset, #ty::FIELD_WIDTH);
+                <#ty as BitFieldSpecifier>::from_u64(val)
             }
 
             pub fn #setter_ident(&mut self, val: <#ty as BitFieldSpecifier>::DefaultFieldType) {
-                debug_assert!((val as u64) <= #ty::FIELD_MAX);
+                let val = <#ty as BitFieldSpecifier>::into_u64(val);
+                debug_assert!(val <= #ty::field_max());
                 let offset = #(#ct1::FIELD_WIDTH as usize)+*;
-                self.set(offset, #ty::FIELD_WIDTH, val as u64)
+                self.set(offset, #ty::FIELD_WIDTH, val)
             }
         });
         current_types.push(ty.clone());
@@ -235,9 +236,14 @@ fn get_tests_impl(struct_name: &Ident, fields: &[(String, TokenStream)]) -> Vec<
             #[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);
+                let val = <#ty as BitFieldSpecifier>::into_u64(a.#getter_ident());
+                assert_eq!(val, 0);
+
+                let val = <#ty as BitFieldSpecifier>::from_u64(#ty::field_max());
+                a.#setter_ident(val);
+
+                let val = <#ty as BitFieldSpecifier>::into_u64(a.#getter_ident());
+                assert_eq!(val, #ty::field_max());
             }
         });
     }
@@ -331,15 +337,17 @@ mod tests {
             #[derive(Clone)]
             struct MyBitField {
                 data: [u8; (BitField1::FIELD_WIDTH as usize
-                    + BitField2::FIELD_WIDTH as usize
-                    + BitField5::FIELD_WIDTH as usize) / 8],
+                            + 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],
+                                   + BitField2::FIELD_WIDTH as usize
+                                   + BitField5::FIELD_WIDTH as usize)
+                            / 8],
                     }
                 }
             }
@@ -396,40 +404,42 @@ mod tests {
             impl MyBitField {
                 pub fn get_a(&self) -> <BitField1 as BitFieldSpecifier>::DefaultFieldType {
                     let offset = BitField0::FIELD_WIDTH as usize;
-                    self.get(offset, BitField1::FIELD_WIDTH)
-                        as <BitField1 as BitFieldSpecifier>::DefaultFieldType
+                    let val = self.get(offset, BitField1::FIELD_WIDTH);
+                    <BitField1 as BitFieldSpecifier>::from_u64(val)
                 }
                 pub fn set_a(&mut self, val: <BitField1 as BitFieldSpecifier>::DefaultFieldType) {
-                    debug_assert!((val as u64) <= BitField1::FIELD_MAX);
+                    let val = <BitField1 as BitFieldSpecifier>::into_u64(val);
+                    debug_assert!(val <= BitField1::field_max());
                     let offset = BitField0::FIELD_WIDTH as usize;
-                    self.set(offset, BitField1::FIELD_WIDTH, val as u64)
+                    self.set(offset, BitField1::FIELD_WIDTH, val)
                 }
                 pub fn get_b(&self) -> <BitField2 as BitFieldSpecifier>::DefaultFieldType {
                     let offset = BitField0::FIELD_WIDTH as usize + BitField1::FIELD_WIDTH as usize;
-                    self.get(offset, BitField2::FIELD_WIDTH)
-                        as <BitField2 as BitFieldSpecifier>::DefaultFieldType
+                    let val = self.get(offset, BitField2::FIELD_WIDTH);
+                    <BitField2 as BitFieldSpecifier>::from_u64(val)
                 }
                 pub fn set_b(&mut self, val: <BitField2 as BitFieldSpecifier>::DefaultFieldType) {
-                    debug_assert!((val as u64) <= BitField2::FIELD_MAX);
+                    let val = <BitField2 as BitFieldSpecifier>::into_u64(val);
+                    debug_assert!(val <= BitField2::field_max());
                     let offset = BitField0::FIELD_WIDTH as usize + BitField1::FIELD_WIDTH as usize;
-                    self.set(offset, BitField2::FIELD_WIDTH, val as u64)
+                    self.set(offset, BitField2::FIELD_WIDTH, val)
                 }
                 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;
-                    self.get(offset, BitField5::FIELD_WIDTH)
-                        as <BitField5 as BitFieldSpecifier>::DefaultFieldType
+                    let val = self.get(offset, BitField5::FIELD_WIDTH);
+                    <BitField5 as BitFieldSpecifier>::from_u64(val)
                 }
                 pub fn set_c(&mut self, val: <BitField5 as BitFieldSpecifier>::DefaultFieldType) {
-                    debug_assert!((val as u64) <= BitField5::FIELD_MAX);
+                    let val = <BitField5 as BitFieldSpecifier>::into_u64(val);
+                    debug_assert!(val <= BitField5::field_max());
                     let offset = BitField0::FIELD_WIDTH as usize
                         + BitField1::FIELD_WIDTH as usize
                         + BitField2::FIELD_WIDTH as usize;
-                    self.set(offset, BitField5::FIELD_WIDTH, val as u64)
+                    self.set(offset, BitField5::FIELD_WIDTH, val)
                 }
             }
-
             impl std::fmt::Debug for MyBitField {
                 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
                     f.debug_struct("MyBitField")
@@ -471,26 +481,32 @@ mod tests {
                 #[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);
+                    let val = <BitField1 as BitFieldSpecifier>::into_u64(a.get_a());
+                    assert_eq!(val, 0);
+                    let val = <BitField1 as BitFieldSpecifier>::from_u64(BitField1::field_max());
+                    a.set_a(val);
+                    let val = <BitField1 as BitFieldSpecifier>::into_u64(a.get_a());
+                    assert_eq!(val, 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);
+                    let val = <BitField2 as BitFieldSpecifier>::into_u64(a.get_b());
+                    assert_eq!(val, 0);
+                    let val = <BitField2 as BitFieldSpecifier>::from_u64(BitField2::field_max());
+                    a.set_b(val);
+                    let val = <BitField2 as BitFieldSpecifier>::into_u64(a.get_b());
+                    assert_eq!(val, 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);
+                    let val = <BitField5 as BitFieldSpecifier>::into_u64(a.get_c());
+                    assert_eq!(val, 0);
+                    let val = <BitField5 as BitFieldSpecifier>::from_u64(BitField5::field_max());
+                    a.set_c(val);
+                    let val = <BitField5 as BitFieldSpecifier>::into_u64(a.get_c());
+                    assert_eq!(val, BitField5::field_max());
                 }
             }
         };
diff --git a/bit_field/src/lib.rs b/bit_field/src/lib.rs
index fdd7993..aa943a3 100644
--- a/bit_field/src/lib.rs
+++ b/bit_field/src/lib.rs
@@ -8,6 +8,17 @@ extern crate bit_field_derive;
 
 pub use bit_field_derive::*;
 
+// This functions calculate max possible number represented by `width` bits. If one day this can be
+// done in other ways, remove this function. For now, stop worrying and trust constant
+// propagation. (checked assembly code, it's a constant when opt-leve >= 2)
+fn max_number_of_width(width: u8) -> u64 {
+    if width < 64 {
+        (1 << width) - 1
+    } else {
+        u64::max_value()
+    }
+}
+
 /// BitFieldSpecifier is a group of structs help defining bitfield. It should only
 /// be used with the #[bitfield] attribute macro.
 /// Example:
@@ -35,466 +46,66 @@ pub use 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;
+    /// Max value of this field.
+    fn field_max() -> u64 {
+        max_number_of_width(Self::FIELD_WIDTH)
+    }
+    fn from_u64(val: u64) -> Self::DefaultFieldType;
+    fn into_u64(val: Self::DefaultFieldType) -> u64;
 }
 
-pub struct BitField1;
-impl BitFieldSpecifier for BitField1 {
+pub struct BitFieldBool;
+impl BitFieldSpecifier for BitFieldBool {
     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;
+    type DefaultFieldType = bool;
+    fn from_u64(val: u64) -> Self::DefaultFieldType {
+        val > 0
+    }
+    fn into_u64(val: Self::DefaultFieldType) -> u64 {
+        val as u64
+    }
+}
+macro_rules! bitfield_structs {
+    ($t:ty, $min_width:expr, $bt:ident $($bts:ident)*)
+    => {
+        pub struct $bt;
+        impl BitFieldSpecifier for $bt {
+            const FIELD_WIDTH: u8 = $min_width;
+            type DefaultFieldType = $t;
+            fn from_u64(val: u64) -> Self::DefaultFieldType {
+                val as Self::DefaultFieldType
+            }
+            fn into_u64(val: Self::DefaultFieldType) -> u64 {
+                val as u64
+            }
+        }
+        bitfield_structs!($t, $min_width + 1, $($bts)*);
+    };
+    ($t:ty, $min_width:expr,) => {};
+}
+
+bitfield_structs! {
+    u8, 0, BitField0 BitField1 BitField2 BitField3 BitField4 BitField5 BitField6 BitField7 BitField8
+}
+
+bitfield_structs! {
+    u16, 9, BitField9 BitField10 BitField11 BitField12 BitField13 BitField14 BitField15 BitField16
+}
+
+bitfield_structs! {
+    u32, 17, BitField17 BitField18 BitField19 BitField20 BitField21 BitField22 BitField23 BitField24
+        BitField25 BitField26 BitField27 BitField28 BitField29 BitField30 BitField31 BitField32
+}
+
+bitfield_structs! {
+    u64, 33, BitField33 BitField34 BitField35 BitField36 BitField37 BitField38 BitField39 BitField40 BitField41
+        BitField42 BitField43 BitField44 BitField45 BitField46 BitField47 BitField48 BitField49 BitField50
+        BitField51 BitField52 BitField53 BitField54 BitField55 BitField56 BitField57 BitField58
+        BitField59 BitField60 BitField61 BitField62 BitField63 BitField64
 }