00001 #ifndef _NX_BITOPS_H
00002 #define _NX_BITOPS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 FILE_LICENCE ( GPL2_OR_LATER );
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 typedef unsigned char pseudo_bit_t;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define NX_PSEUDO_BIT_STRUCT( _structure ) \
00044 union { \
00045 uint8_t bytes[ sizeof ( _structure ) / 8 ]; \
00046 uint64_t qwords[ sizeof ( _structure ) / 64 ]; \
00047 _structure *dummy[0]; \
00048 } u;
00049
00050
00051 #define NX_PSEUDO_STRUCT( _ptr ) \
00052 typeof ( *((_ptr)->u.dummy[0]) )
00053
00054
00055 #define NX_BIT_OFFSET( _ptr, _field ) \
00056 offsetof ( NX_PSEUDO_STRUCT ( _ptr ), _field )
00057
00058
00059 #define NX_BIT_WIDTH( _ptr, _field ) \
00060 sizeof ( ( ( NX_PSEUDO_STRUCT ( _ptr ) * ) NULL )->_field )
00061
00062
00063 #define NX_QWORD_OFFSET( _ptr, _field ) \
00064 ( NX_BIT_OFFSET ( _ptr, _field ) / 64 )
00065
00066
00067
00068
00069
00070
00071 #define NX_QWORD_BIT_OFFSET( _ptr, _index, _field ) \
00072 ( NX_BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) )
00073
00074
00075 #define NX_BIT_MASK( _ptr, _field ) \
00076 ( ( ~( ( uint64_t ) 0 ) ) >> \
00077 ( 64 - NX_BIT_WIDTH ( _ptr, _field ) ) )
00078
00079
00080
00081
00082
00083
00084 #define NX_ASSEMBLE_1( _ptr, _index, _field, _value ) \
00085 ( ( ( uint64_t) (_value) ) << \
00086 NX_QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
00087
00088 #define NX_ASSEMBLE_2( _ptr, _index, _field, _value, ... ) \
00089 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00090 NX_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
00091
00092 #define NX_ASSEMBLE_3( _ptr, _index, _field, _value, ... ) \
00093 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00094 NX_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
00095
00096 #define NX_ASSEMBLE_4( _ptr, _index, _field, _value, ... ) \
00097 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00098 NX_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
00099
00100 #define NX_ASSEMBLE_5( _ptr, _index, _field, _value, ... ) \
00101 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00102 NX_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
00103
00104 #define NX_ASSEMBLE_6( _ptr, _index, _field, _value, ... ) \
00105 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00106 NX_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
00107
00108 #define NX_ASSEMBLE_7( _ptr, _index, _field, _value, ... ) \
00109 ( NX_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00110 NX_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
00111
00112
00113
00114
00115
00116
00117 #define NX_MASK_1( _ptr, _index, _field ) \
00118 ( NX_BIT_MASK ( _ptr, _field ) << \
00119 NX_QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
00120
00121 #define NX_MASK_2( _ptr, _index, _field, ... ) \
00122 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00123 NX_MASK_1 ( _ptr, _index, __VA_ARGS__ ) )
00124
00125 #define NX_MASK_3( _ptr, _index, _field, ... ) \
00126 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00127 NX_MASK_2 ( _ptr, _index, __VA_ARGS__ ) )
00128
00129 #define NX_MASK_4( _ptr, _index, _field, ... ) \
00130 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00131 NX_MASK_3 ( _ptr, _index, __VA_ARGS__ ) )
00132
00133 #define NX_MASK_5( _ptr, _index, _field, ... ) \
00134 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00135 NX_MASK_4 ( _ptr, _index, __VA_ARGS__ ) )
00136
00137 #define NX_MASK_6( _ptr, _index, _field, ... ) \
00138 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00139 NX_MASK_5 ( _ptr, _index, __VA_ARGS__ ) )
00140
00141 #define NX_MASK_7( _ptr, _index, _field, ... ) \
00142 ( NX_MASK_1 ( _ptr, _index, _field ) | \
00143 NX_MASK_6 ( _ptr, _index, __VA_ARGS__ ) )
00144
00145
00146
00147
00148
00149
00150 #define NX_FILL( _ptr, _index, _assembled ) \
00151 do { \
00152 uint64_t *__ptr = &(_ptr)->u.qwords[(_index)]; \
00153 uint64_t __assembled = (_assembled); \
00154 *__ptr = cpu_to_le64 ( __assembled ); \
00155 } while ( 0 )
00156
00157 #define NX_FILL_1( _ptr, _index, ... ) \
00158 NX_FILL ( _ptr, _index, NX_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
00159
00160 #define NX_FILL_2( _ptr, _index, ... ) \
00161 NX_FILL ( _ptr, _index, NX_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
00162
00163 #define NX_FILL_3( _ptr, _index, ... ) \
00164 NX_FILL ( _ptr, _index, NX_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
00165
00166 #define NX_FILL_4( _ptr, _index, ... ) \
00167 NX_FILL ( _ptr, _index, NX_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
00168
00169 #define NX_FILL_5( _ptr, _index, ... ) \
00170 NX_FILL ( _ptr, _index, NX_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
00171
00172 #define NX_FILL_6( _ptr, _index, ... ) \
00173 NX_FILL ( _ptr, _index, NX_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
00174
00175 #define NX_FILL_7( _ptr, _index, ... ) \
00176 NX_FILL ( _ptr, _index, NX_ASSEMBLE_7 ( _ptr, _index, __VA_ARGS__ ) )
00177
00178
00179 #define NX_GET64( _ptr, _field ) \
00180 ( { \
00181 unsigned int __index = NX_QWORD_OFFSET ( _ptr, _field ); \
00182 uint64_t *__ptr = &(_ptr)->u.qwords[__index]; \
00183 uint64_t __value = le64_to_cpu ( *__ptr ); \
00184 __value >>= \
00185 NX_QWORD_BIT_OFFSET ( _ptr, __index, _field ); \
00186 __value &= NX_BIT_MASK ( _ptr, _field ); \
00187 __value; \
00188 } )
00189
00190
00191 #define NX_GET( _ptr, _field ) \
00192 ( ( unsigned long ) NX_GET64 ( _ptr, _field ) )
00193
00194 #endif