blob: a2fc6784d1ed3999c2cd1a2ec1da3f34e430f31d [file] [log] [blame]
/* 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); })