| /* Copyright (c) 2015 Google Inc |
| * Davide Libenzi <dlibenzi@google.com> |
| * See LICENSE for details. |
| * |
| * This file provide an interface for dealing with bitfields, without |
| * having to explicitly create by hand masks and shifts definitions |
| * and operational macros. |
| * Example use: |
| * |
| * #define MYBF_X MKBITFIELD(0, 4) |
| * #define MYBF_Y MKBITFIELD(4, 3) |
| * #define MYBF_Z MKBITFIELD(7, 25) |
| * |
| * #define MYBF_GET_X(v) BF_GETFIELD(v, MYBF_X) |
| * #define MYBF_SET_X(v, x) BF_SETFIELD(v, x, MYBF_X) |
| * #define MYBF_GET_Y(v) BF_GETFIELD(v, MYBF_Y) |
| * #define MYBF_SET_Y(v, x) BF_SETFIELD(v, x, MYBF_Y) |
| * #define MYBF_GET_Z(v) BF_GETFIELD(v, MYBF_Z) |
| * #define MYBF_SET_Z(v, x) BF_SETFIELD(v, x, MYBF_Z) |
| */ |
| |
| #pragma once |
| |
| #include <stdint.h> |
| |
| struct bitfield_conf { |
| uint8_t shift; |
| uint8_t nbits; |
| }; |
| |
| #define MKBITFIELD(s, n) \ |
| ((struct bitfield_conf) { .shift = (s), .nbits = (n) }) |
| |
| #define BF_MKMASK(type, bfc) ((((type) 1 << bfc.nbits) - 1) << bfc.shift) |
| |
| #define BF_GETFIELD(val, bfc) \ |
| ({ ((val) >> bfc.shift) & (((typeof(val)) 1 << bfc.nbits) - 1); }) |
| |
| #define BF_SETFIELD(val, x, bfc) \ |
| ({ typeof(val) m = BF_MKMASK(typeof(val), bfc); \ |
| (val) = ((val) & ~m) | \ |
| (((typeof(val)) (x) << bfc.shift) & m); }) |