|
| 1 | +//! Tests for `BindgenBitfieldUnit`. |
| 2 | +//! |
| 3 | +//! Note that bit-fields are allocated right to left (least to most significant |
| 4 | +//! bits). |
| 5 | +//! |
| 6 | +//! From the x86 PS ABI: |
| 7 | +//! |
| 8 | +//! ```c |
| 9 | +//! struct { |
| 10 | +//! int j : 5; |
| 11 | +//! int k : 6; |
| 12 | +//! int m : 7; |
| 13 | +//! }; |
| 14 | +//! ``` |
| 15 | +//! |
| 16 | +//! ```ignore |
| 17 | +//! +------------------------------------------------------------+ |
| 18 | +//! | | | | | |
| 19 | +//! | padding | m | k | j | |
| 20 | +//! |31 18|17 11|10 5|4 0| |
| 21 | +//! +------------------------------------------------------------+ |
| 22 | +//! ``` |
| 23 | +
|
| 24 | +use super::bitfield_unit::BindgenBitfieldUnit; |
| 25 | +use std::mem; |
| 26 | + |
| 27 | +#[test] |
| 28 | +fn bitfield_unit_get_bit() { |
| 29 | + let unit = BindgenBitfieldUnit::<[u8; 2], u64>::new([0b10011101, 0b00011101]); |
| 30 | + |
| 31 | + let mut bits = vec![]; |
| 32 | + for i in 0..16 { |
| 33 | + bits.push(unit.get_bit(i)); |
| 34 | + } |
| 35 | + |
| 36 | + println!(); |
| 37 | + println!("bits = {:?}", bits); |
| 38 | + assert_eq!(bits, &[ |
| 39 | + // 0b00011101 |
| 40 | + true, |
| 41 | + false, |
| 42 | + true, |
| 43 | + true, |
| 44 | + true, |
| 45 | + false, |
| 46 | + false, |
| 47 | + false, |
| 48 | + |
| 49 | + // 0b10011101 |
| 50 | + true, |
| 51 | + false, |
| 52 | + true, |
| 53 | + true, |
| 54 | + true, |
| 55 | + false, |
| 56 | + false, |
| 57 | + true |
| 58 | + ]); |
| 59 | +} |
| 60 | + |
| 61 | +#[test] |
| 62 | +fn bitfield_unit_set_bit() { |
| 63 | + let mut unit = BindgenBitfieldUnit::<[u8; 2], u64>::new([0b00000000, 0b00000000]); |
| 64 | + |
| 65 | + for i in 0..16 { |
| 66 | + if i % 3 == 0 { |
| 67 | + unit.set_bit(i, true); |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + for i in 0..16 { |
| 72 | + assert_eq!(unit.get_bit(i), i % 3 == 0); |
| 73 | + } |
| 74 | + |
| 75 | + let mut unit = BindgenBitfieldUnit::<[u8; 2], u64>::new([0b11111111, 0b11111111]); |
| 76 | + |
| 77 | + for i in 0..16 { |
| 78 | + if i % 3 == 0 { |
| 79 | + unit.set_bit(i, false); |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + for i in 0..16 { |
| 84 | + assert_eq!(unit.get_bit(i), i % 3 != 0); |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +#[test] |
| 89 | +fn bitfield_unit_align() { |
| 90 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 1], u8>>(), mem::align_of::<u8>()); |
| 91 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 1], u16>>(), mem::align_of::<u16>()); |
| 92 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 1], u32>>(), mem::align_of::<u32>()); |
| 93 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 1], u64>>(), mem::align_of::<u64>()); |
| 94 | + |
| 95 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 8], u8>>(), mem::align_of::<u8>()); |
| 96 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 8], u16>>(), mem::align_of::<u16>()); |
| 97 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 8], u32>>(), mem::align_of::<u32>()); |
| 98 | + assert_eq!(mem::align_of::<BindgenBitfieldUnit<[u8; 8], u64>>(), mem::align_of::<u64>()); |
| 99 | +} |
| 100 | + |
| 101 | +macro_rules! bitfield_unit_get { |
| 102 | + ( |
| 103 | + $( |
| 104 | + With $storage:expr , then get($start:expr, $len:expr) is $expected:expr; |
| 105 | + )* |
| 106 | + ) => { |
| 107 | + #[test] |
| 108 | + fn bitfield_unit_get() { |
| 109 | + $({ |
| 110 | + let expected = $expected; |
| 111 | + let unit = BindgenBitfieldUnit::<_, u64>::new($storage); |
| 112 | + let actual = unit.get($start, $len); |
| 113 | + |
| 114 | + println!(); |
| 115 | + println!("expected = {:064b}", expected); |
| 116 | + println!("actual = {:064b}", actual); |
| 117 | + |
| 118 | + assert_eq!(expected, actual); |
| 119 | + })* |
| 120 | + } |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +bitfield_unit_get! { |
| 125 | + // Let's just exhaustively test getting the bits from a single byte, since |
| 126 | + // there are few enough combinations... |
| 127 | + |
| 128 | + With [0b11100010], then get(0, 1) is 0; |
| 129 | + With [0b11100010], then get(1, 1) is 1; |
| 130 | + With [0b11100010], then get(2, 1) is 0; |
| 131 | + With [0b11100010], then get(3, 1) is 0; |
| 132 | + With [0b11100010], then get(4, 1) is 0; |
| 133 | + With [0b11100010], then get(5, 1) is 1; |
| 134 | + With [0b11100010], then get(6, 1) is 1; |
| 135 | + With [0b11100010], then get(7, 1) is 1; |
| 136 | + |
| 137 | + With [0b11100010], then get(0, 2) is 0b10; |
| 138 | + With [0b11100010], then get(1, 2) is 0b01; |
| 139 | + With [0b11100010], then get(2, 2) is 0b00; |
| 140 | + With [0b11100010], then get(3, 2) is 0b00; |
| 141 | + With [0b11100010], then get(4, 2) is 0b10; |
| 142 | + With [0b11100010], then get(5, 2) is 0b11; |
| 143 | + With [0b11100010], then get(6, 2) is 0b11; |
| 144 | + |
| 145 | + With [0b11100010], then get(0, 3) is 0b010; |
| 146 | + With [0b11100010], then get(1, 3) is 0b001; |
| 147 | + With [0b11100010], then get(2, 3) is 0b000; |
| 148 | + With [0b11100010], then get(3, 3) is 0b100; |
| 149 | + With [0b11100010], then get(4, 3) is 0b110; |
| 150 | + With [0b11100010], then get(5, 3) is 0b111; |
| 151 | + |
| 152 | + With [0b11100010], then get(0, 4) is 0b0010; |
| 153 | + With [0b11100010], then get(1, 4) is 0b0001; |
| 154 | + With [0b11100010], then get(2, 4) is 0b1000; |
| 155 | + With [0b11100010], then get(3, 4) is 0b1100; |
| 156 | + With [0b11100010], then get(4, 4) is 0b1110; |
| 157 | + |
| 158 | + With [0b11100010], then get(0, 5) is 0b00010; |
| 159 | + With [0b11100010], then get(1, 5) is 0b10001; |
| 160 | + With [0b11100010], then get(2, 5) is 0b11000; |
| 161 | + With [0b11100010], then get(3, 5) is 0b11100; |
| 162 | + |
| 163 | + With [0b11100010], then get(0, 6) is 0b100010; |
| 164 | + With [0b11100010], then get(1, 6) is 0b110001; |
| 165 | + With [0b11100010], then get(2, 6) is 0b111000; |
| 166 | + |
| 167 | + With [0b11100010], then get(0, 7) is 0b1100010; |
| 168 | + With [0b11100010], then get(1, 7) is 0b1110001; |
| 169 | + |
| 170 | + With [0b11100010], then get(0, 8) is 0b11100010; |
| 171 | + |
| 172 | + // OK. Now let's test getting bits from across byte boundaries. |
| 173 | + |
| 174 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 175 | + then get(0, 16) is 0b0000000011111111; |
| 176 | + |
| 177 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 178 | + then get(1, 16) is 0b1000000001111111; |
| 179 | + |
| 180 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 181 | + then get(2, 16) is 0b1100000000111111; |
| 182 | + |
| 183 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 184 | + then get(3, 16) is 0b1110000000011111; |
| 185 | + |
| 186 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 187 | + then get(4, 16) is 0b1111000000001111; |
| 188 | + |
| 189 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 190 | + then get(5, 16) is 0b1111100000000111; |
| 191 | + |
| 192 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 193 | + then get(6, 16) is 0b1111110000000011; |
| 194 | + |
| 195 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 196 | + then get(7, 16) is 0b1111111000000001; |
| 197 | + |
| 198 | + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], |
| 199 | + then get(8, 16) is 0b1111111100000000; |
| 200 | +} |
| 201 | + |
| 202 | +macro_rules! bitfield_unit_set { |
| 203 | + ( |
| 204 | + $( |
| 205 | + set($start:expr, $len:expr, $val:expr) is $expected:expr; |
| 206 | + )* |
| 207 | + ) => { |
| 208 | + #[test] |
| 209 | + fn bitfield_unit_set() { |
| 210 | + $( |
| 211 | + let mut unit = BindgenBitfieldUnit::<[u8; 4], u64>::new([0, 0, 0, 0]); |
| 212 | + unit.set($start, $len, $val); |
| 213 | + let actual = unit.get(0, 32); |
| 214 | + |
| 215 | + println!(); |
| 216 | + println!("set({}, {}, {:032b}", $start, $len, $val); |
| 217 | + println!("expected = {:064b}", $expected); |
| 218 | + println!("actual = {:064b}", actual); |
| 219 | + |
| 220 | + assert_eq!($expected, actual); |
| 221 | + )* |
| 222 | + } |
| 223 | + } |
| 224 | +} |
| 225 | + |
| 226 | +bitfield_unit_set! { |
| 227 | + // Once again, let's exhaustively test single byte combinations. |
| 228 | + |
| 229 | + set(0, 1, 0b11111111) is 0b00000001; |
| 230 | + set(1, 1, 0b11111111) is 0b00000010; |
| 231 | + set(2, 1, 0b11111111) is 0b00000100; |
| 232 | + set(3, 1, 0b11111111) is 0b00001000; |
| 233 | + set(4, 1, 0b11111111) is 0b00010000; |
| 234 | + set(5, 1, 0b11111111) is 0b00100000; |
| 235 | + set(6, 1, 0b11111111) is 0b01000000; |
| 236 | + set(7, 1, 0b11111111) is 0b10000000; |
| 237 | + |
| 238 | + set(0, 2, 0b11111111) is 0b00000011; |
| 239 | + set(1, 2, 0b11111111) is 0b00000110; |
| 240 | + set(2, 2, 0b11111111) is 0b00001100; |
| 241 | + set(3, 2, 0b11111111) is 0b00011000; |
| 242 | + set(4, 2, 0b11111111) is 0b00110000; |
| 243 | + set(5, 2, 0b11111111) is 0b01100000; |
| 244 | + set(6, 2, 0b11111111) is 0b11000000; |
| 245 | + |
| 246 | + set(0, 3, 0b11111111) is 0b00000111; |
| 247 | + set(1, 3, 0b11111111) is 0b00001110; |
| 248 | + set(2, 3, 0b11111111) is 0b00011100; |
| 249 | + set(3, 3, 0b11111111) is 0b00111000; |
| 250 | + set(4, 3, 0b11111111) is 0b01110000; |
| 251 | + set(5, 3, 0b11111111) is 0b11100000; |
| 252 | + |
| 253 | + set(0, 4, 0b11111111) is 0b00001111; |
| 254 | + set(1, 4, 0b11111111) is 0b00011110; |
| 255 | + set(2, 4, 0b11111111) is 0b00111100; |
| 256 | + set(3, 4, 0b11111111) is 0b01111000; |
| 257 | + set(4, 4, 0b11111111) is 0b11110000; |
| 258 | + |
| 259 | + set(0, 5, 0b11111111) is 0b00011111; |
| 260 | + set(1, 5, 0b11111111) is 0b00111110; |
| 261 | + set(2, 5, 0b11111111) is 0b01111100; |
| 262 | + set(3, 5, 0b11111111) is 0b11111000; |
| 263 | + |
| 264 | + set(0, 6, 0b11111111) is 0b00111111; |
| 265 | + set(1, 6, 0b11111111) is 0b01111110; |
| 266 | + set(2, 6, 0b11111111) is 0b11111100; |
| 267 | + |
| 268 | + set(0, 7, 0b11111111) is 0b01111111; |
| 269 | + set(1, 7, 0b11111111) is 0b11111110; |
| 270 | + |
| 271 | + set(0, 8, 0b11111111) is 0b11111111; |
| 272 | + |
| 273 | + // And, now let's cross byte boundaries. |
| 274 | + |
| 275 | + set(0, 16, 0b1111111111111111) is 0b00000000000000001111111111111111; |
| 276 | + set(1, 16, 0b1111111111111111) is 0b00000000000000011111111111111110; |
| 277 | + set(2, 16, 0b1111111111111111) is 0b00000000000000111111111111111100; |
| 278 | + set(3, 16, 0b1111111111111111) is 0b00000000000001111111111111111000; |
| 279 | + set(4, 16, 0b1111111111111111) is 0b00000000000011111111111111110000; |
| 280 | + set(5, 16, 0b1111111111111111) is 0b00000000000111111111111111100000; |
| 281 | + set(6, 16, 0b1111111111111111) is 0b00000000001111111111111111000000; |
| 282 | + set(7, 16, 0b1111111111111111) is 0b00000000011111111111111110000000; |
| 283 | + set(8, 16, 0b1111111111111111) is 0b00000000111111111111111100000000; |
| 284 | +} |
0 commit comments