/*
** mg_bit.c for  in 
** 
** Made by vianney rancurel
** Login   <vianney@epita.fr>
** 
** Started on  Wed Aug 25 12:16:43 1999 vianney rancurel
** Last update Thu Oct 28 20:16:28 1999 
*/
#include "mg.h"

#ifndef NBBY
# define NBBY	8
#endif 

#define BITFIELDGET(Proc,Type) \
VOID_FUNC	Proc(valp,retvalp,from,to)\
Type		*valp;\
Type		*retvalp;\
int		from;\
int		to;\
{\
  Type		val;\
\
  val = *valp;\
  val <<= from;\
  val >>= from;\
  val >>= (((sizeof (Type) * NBBY) - 1) - to);\
  *retvalp = val;\
}

#define BITFIELDSET(Proc,Type) \
VOID_FUNC	Proc(valp,from,to,value)\
Type		*valp;\
int		from;\
int		to;\
int		value;\
{\
  Type		val;\
  int		nbits;\
  Type		mask;\
\
  nbits = to - from;\
  val = *valp;\
  mask = ~0;\
  value <<= (((sizeof (Type) * NBBY) - 1) - nbits);\
  mask <<= (((sizeof (Type) * NBBY) - 1) - nbits);\
  value >>= (((sizeof (Type) * NBBY) - 1) - nbits);\
  mask >>= (((sizeof (Type) * NBBY) - 1) - nbits);\
  value <<= (((sizeof (Type) * NBBY) - 1) - to);\
  mask <<= (((sizeof (Type) * NBBY) - 1) - to);\
  mask = ~mask;\
  val &= mask;\
  val |= value;\
  *valp = val;\
}

/* extracts or insert bitfield values delimited by "from" and "to".
   Note: "From" is starting from 0. The first bit is designed as [0,0].
   "Value" must not override its range (2^(from-to)) because there is no
   guarantee of the result (I've tried to shift bits on the left to lose
   their values but it doesn't work: some help here will be very apprecied).

   Warning: It doesn't deal with alignment. */

BITFIELDGET(bit_field_u8_get,t_u8)
BITFIELDGET(bit_field_u16_get,t_u16)
BITFIELDGET(bit_field_u32_get,t_u32)

BITFIELDSET(bit_field_u8_set,t_u8)
BITFIELDSET(bit_field_u16_set,t_u16)
BITFIELDSET(bit_field_u32_set,t_u32)
