How masking works - c++

I am new at C, and I am debugging with source code. However, I am confused with this code snippet.
When the values are assigned to the structure value, I think it is some masking. But not sure, and if it is masking. How does masking work in this concept?
Many thanks,
#define MSGINFO_ENABLE 0x01
#define MIME_ENABLE 0x02
#define FASTSTART_CODERS_IN_OFFERED 0x04
#define TRANSADDR_ENABLE 0x08
typedef struct {
unsigned int msginfo_mask; /* added in version 0x0101 */
} VIRTBOARD;
VIRTBOARD VirtBoard;
/* Not sure I understand what is happening here. */
VirtBoard.msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE | FASTSTART_CODERS_IN_OFFERED | TRANSADDR_ENABLE;

Ok in plain English:
The Hexdecimal numbers 0x01,0x02,0x04,0x08 were each selected BECAUSE they are each encoded as different single bits being set in binary. None of the bit maps overlap so each one can be read and set without being effected by the other bits. Adding the following comments to your code makes it clearer what's happening:
#define MSGINFO_ENABLE 0x01 // => 0001
#define MIME_ENABLE 0x02 // => 0010
#define FASTSTART_CODERS_IN_OFFERED 0x04 // => 0100
#define TRANSADDR_ENABLE 0x08 // => 1000
Now adding a comment before the other line shows the result:
// VirtBoard.msginfo_mask |= 0001
// VirtBoard.msginfo_mask |= 0010
// VirtBoard.msginfo_mask |= 0100
// VirtBoard.msginfo_mask |= 1000
// ----
// VirtBoard.msginfo_mask == 1111
VirtBoard.msginfo_mask = MSGINFO_ENABLE |
MIME_ENABLE |
FASTSTART_CODERS_IN_OFFERED |
TRANSADDR_ENABLE;
While the comments on the assignment make it clear what's going on, once you understand what's happening, the comments kinda defeat the purpose of symbolically defining constants.

It might help to think of it this way (values shown in binary):
MSGINFO_ENABLE = 0001
MIME_ENABLE = 0010
FASTSTART_CODERS_IN_OFFERED = 0100
TRANSADDR_ENABLE = 1000
So...
1001 is TRANSADDR_ENABLE and MSGINFO_ENABLE
or
1101 is eveything but FASTSTART_CODERS_IN_OFFERED
Does that help at all? The | notation is C syntax to set the correct bit:
int something = 0;
something = MSGINFO_ENABLE | TRANSADDR_ENABLE;
is the a syntax to set only those 2 bits.

Your variable, msginfo_mask, when represented as a binary number (1's and 0's) is used as a "mask" by setting certain bits to 1 (using bit-wise OR) or clearing certain bits to 0 (using bit-wise AND). Your code snippet sets certain bits to 1 while leaving others unchanged. Masking is comparable to how a painter masks off areas that they do not want to be painted.
If you look at the #defines at the top of your code, you will notice that each number represents a single bit when written out in binary:
#define MSGINFO_ENABLE 0x01 <-- 0001 in binary
#define MIME_ENABLE 0x02 <-- 0010 in binary
#define FASTSTART_CODERS_IN_OFFERED 0x04 <-- 0100 in binary
#define TRANSADDR_ENABLE 0x08 <-- 1000 in binary
Setting bits is done by using the OR function. If you OR a bit with 1, the result is always going to be a 1. If you OR a bit with 0, the original value will not be changed.
So, when you see:
msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE |
FASTSTART_CODERS_IN_OFFERED | TRANSADDR_ENABLE;
What you are saying is "take the value of msginfo_mask and OR it with (binary) 0001, 0010, 0100, and 1000. This is the same thing as saying "set bit 0, bit 1, bit 2, and bit 3."

The binary operator '|' is the bitwise-or operator; for each bit in the two input words, if either bit is a 1, then the corresponding bit in the result is a 1:
0001 | 0010 = 0011
The '|' operator is typically used to set individual bits in a word, such as in the code snippet you posted.
The binary operator '&' is the bitwise-and operator; for each bit in the two input words, if both bits are 1, then the corresponding bit in the result is a 1:
0101 & 0110 = 0100
The '&' operator can be used to test if a bit is set. For example, to test if the MSGINFO_ENABLE bit is set, you'd do something like
if (VirtBoard.msginfo_mask & MSGINFO_ENABLE != 0)
{
/* MSGINFO_ENABLE bit is set, do something interesting */
}
The expression
VirtBoard.msginfo_mask & MSGINFO_ENABLE
will evaluate to 1 (0x0001) if the MSGINFO_ENABLE bit was set,0 otherwise.
The unary operator '~' is the bitwise-not operator; for each bit in the input word, the corresponding bit in the result is set to the opposite value:
~ 0001 = 1110
You can use the '~' operator together with the '&' operator to clear an individual bit. For example, if we wanted to clear the MSGINFO_ENABLE bit, we'd do something like
VirtBoard.msginfo_mask = VirtBoard.msginfo_mask & ~MSGINFO_ENABLE;
which can be shortened to
VirtBoard.msginfo_mask &= ~MSGINFO_ENABLE;
Negating MSGINFO_ ENABLE gives us 1111111111111110 (assuming a 16-bit unsigned int); since the leading bits are all 1, and-ing this against the VirtBoard.msginfo_ mask preserves any bits that are already set; i.e., 0000000000001111 & 1111111111111110 = 0000000000001110.
If we wanted to clear both the MSGINFO _ENABLE and TRANSADDR _ENABLE bits, we'd combine all the operators like so:
VirtBoard.msginfo_mask &= ~(MSGINFO_ENABLE | TRANSADDER_ENABLE)

The programmer is setting the mask to a certain bit value. In this case:
VitBoard.msginfo_mask = 0x01 | 0x02 | 0x04 = 0x07
Assuming the code handles messages, when a message comes in they may compare it to this mask to see what is enabled in the message.
if((newMsg & VitBoard.msginfo_mask) == 0x07)
{
//do something related to mime enable, msginfo enable and faststart
}
Notice the "&" operator to do the mask comparisons.

The other part is that "or" the masks together are probably being used as switches to enable/disable certain functionality. In the examples you have written, it looks like possibly output at different levels or parts of the codes.
The defined masks can be used to check the functionality to see if it is enable or disabled. For example:
VirtBoard.msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE ;
if ( VirtBoard.msginfo_mask & MSGINFO_ENABLE )
{
printf("Messages enabled\n";
}
if ( VirtBoard.msginfo_mask & TRANSADDR_ENABLE)
{
printf("Transaddress enabled\n");
}
In the first if, since MSGINFO_ENABLED mask was "or" and assigned to the variable, when you apply an "and" operation with the variable and MSGINOF_ENABLED mask, a non zero value is returned, indicating it is true. So the printf statement will be executed.
In the case of the second if, since TRANSADDR_ENABLE was not "or" in to the variable, when an "and" is used with the variable and TRANSADDR_ENABLE mask, it will return a zero value, so no message will be printed.

Related

fastest way to convert int8 to int7

I've a function that takes int8_t val and converts it to int7_t.
//Bit [7] reserved
//Bits [6:0] = signed -64 to +63 offset value
// user who calls this function will use it correctly (-64 to +63)
uint8_t func_int7_t(int8_t val){
uint8_t val_6 = val & 0b01111111;
if (val & 0x80)
val_6 |= 0x40;
//...
//do stuff...
return val_6;
}
What is the best and fastest way to manipulate the int8 to int7? Did I do it efficient and fast? or there is better way?
The target is ARM Cortex M0+ if that matters
UPDATE:
After reading different answers I can say the question was asked wrong? (or my code in the question is what gave wrong assumptions to others) I had the intension to make an int8 to int7
So it will be done by doing nothing because
8bit:
63 = 0011 1111
62 = 0011 1110
0 = 0000 0000
-1 = 1111 1111
-2 = 1111 1110
-63 = 1100 0001
-64 = 1100 0000
7bit:
63 = 011 1111
62 = 011 1110
0 = 000 0000
-1 = 111 1111
-2 = 111 1110
-63 = 100 0001
-64 = 100 0000
the faster way is probably :
uint8_t val_7 = (val & 0x3f) | ((val >> 1) & 0x40);
val & 0x3f get the 6 lower bits (truncate) and ((val >> 1) & 0x40) move the bit to sign from the position 8 to 7
The advantage to not use a if is to have a shorter code (even you can use arithmetic if) and to have a code without sequence break
To clear the reserved bit, just
return val & 0x7f;
To leave the reserved bit exactly like how it was from input, nothing needs to be done
return val;
and the low 7 bits will contain the values in [-64, 63]. Because in two's complement down casting is done by a simple truncation. The value remains the same. That's what happens for an assignment like (int8_t)some_int_value
There's no such thing as 0bX1100001. There's no undefined bit in machine language. That state only exists in hardware, like the high-Z state or undefined state in Verilog or other hardware description languages
Use bitfield to narrow the value and let compiler to choose what sequence of shifts and/or masks is most efficient for that on your platform.
inline uint8_t to7bit(int8_t x)
{
struct {uint8_t x:7;} s;
return s.x = x;
}
If you are not concerned about what happens to out-of-range values, then
return val & 0x7f;
is enough. This correctly handles values in the range -64 <= val <= 63.
You haven't said how you want to handle out-of-range values, so I have nothing to say about that.
Updated to add: The question has been updated so stipulate that the function will never be called with out-of-range values. So this method qualifies unambiguously as "best and fastest".
the user who calls this function he knows he should put data -64 to +63
So not considering any other values, the really fastest thing you can do is not doing anything at all!
You have a 7 bit value stored in eight bits. Any value within specified range will have both bit 7 and bit 6 the same value, and when you process the 7-bit value, you just ignore the MSB (of 8-bit value), no matter if set or not, e. g.:
for(unsigned int bit = 0x40; bit; bit >>= 1)
// NOT: 0x80!
std::cout << (value & bit);
The other way round is more critical: whenever you receive these seven bits via some communication channel, then you need to do manual sign extension for eight (or more) bits to be able to correctly use that value.

Unusual CString formatting

I have such code:
int value = 65536;
CString output = TEXT("");
output.Format(TEXT("%X"), value);
Printing output gives me: 10000
I need output like this: 0001.0000
Is it possible?
It seems to me I have found answer:
output.Format(TEXT("%.4X.%.4X"), (value >> 16) & 0xffff, value & 0xffff);
You have to mast byte you don't want and leave all others.
Assuming int is 32 bits on your platform you have:
Byte 4 3 2 1
Binary | 0000 0000 | 0000 0000 | 0000 0001 | 0000 0000 |
Hex 0x00 0x01 0x00 0x00
What you want is to isolate byte 1-2 and byte 3-4
Byte 1-2: simply mask all others bits using 0x0000FFFF or simply 0xFFFF
Byte 3-4: move left for 16 byts of bytes 1-2. Not your case but to be sure to print only value of those bytes mask all other bits.
Your code can be:
output.Format(TEXT("%04X.%04X"), (value >> 16) & 0xFFFF, (value & 0xFFFF));
Printing output gives me: 10000
The "%X" format string works just as expected.
I need output like this: 0001.0000
If I might ask, what's the point of using a floating point decimal representation? Hexadecimal is used because it translates directly to binary, otherwise there's no point using it.
But anyway if you really need it, the CString::format()'s formatting string is the same as printf()'s:
%A Hexadecimal floating point, uppercase
So replace %F by %A and cast your variable as a float it should do the trick!

What does "variable|variable" mean in C++?

I was looking into this ITE8712 watchdog timer demo code when I saw this:
void InitWD(char cSetWatchDogUnit, char cSetTriggerSignal)
{
OpenIoConfig(); //open super IO of configuration for Super I/O
SelectIoDevice(0x07); //select device7
//set watch dog counter of unit
WriteIoCR(0x72, cSetWatchDogUnit|cSetTriggerSignal);
//CloseIoConfig(); //close super IO of configuration for Super I/O
}
and, I wonder what is meant by this line:
cSetWatchDogUnit|cSetTriggerSignal
because the WriteIoCR function looks like this:
void WriteIoCR(char cIndex, char cData)
{
//super IO of index port for Super I/O
//select super IO of index register for Super I/O
outportb(equIndexPort,cIndex);
//super IO of data for Super I/O
//write data to data register
outportb(equDataPort,cData);
}
So cIndex should be 0x72, but what about the cData? I really don't get the "|" thing as I've only used it for OR ("||") in a conditional statement.
It's a bitwise or, as distinct to your normal logical or. It basically sets the bits in the target variable if the corresponding bit in either of the source variables was set.
For example, the expression 43 | 17 can be calculated as:
43 = 0x2b = binary 0010 1011
17 = 0x11 = binary 0001 0001
==== ====
"or" them: 0011 1011 = 0x3b = 59
See this answer for a more thorough examination of the various bitwise operators.
It's typically used when you want to manipulate specific bits within a data type, such as control of a watchdog timer in an embedded system (your particular use case).
You can use or (|) to turn bits on and and (&) to turn them off (with the inversion of the bitmask that's used to turn them on.
So, to turn on the b3 bit, use:
val = val | 0x08; // 0000 1000
To turn it off, use:
val = val & 0xf7; // 1111 0111
To detect if b3 is currently set, use:
if ((val & 0x08) != 0) {
// it is set.
}
You'll typically see the bitmasks defined something like:
#define B0 0x01
#define B1 0x02
#define B2 0x04
#define B3 0x08
#define B4 0x10
or:
enum BitMask {
B0 = 0x01,
B1 = 0x02,
B2 = 0x04,
B3 = 0x08,
B4 = 0x10
};
As to what this means:
WriteIoCR (0x72, cSetWatchDogUnit|cSetTriggerSignal);
More than likely, 0x72 will be an I/O port of some sort that you're writing to and cSetWatchDogUnit and cSetTriggerSignal will be bitmasks that you combine to output the command (set the trigger signal and use a unit value for the watchdog). What that command means in practice can be inferred but you're safer referring to the documentation for the watchdog circuitry itself.
And, on the off chance that you don't know what a watchdog circuit is for, it's a simple circuit that, if you don't kick it often enough (with another command), it will reset your system, probably by activating the reset pin on whatever processor you're using.
It's a way to detect badly behaving software automatically and return a device to a known initial state, subscribing to the theory that it's better to reboot than continue executing badly.
That's a bitwise or.
It is used here to combine flags.
x | y is generally used with Plain Old Datas in C/C++. It means bitwise OR.
e.g.
char x = 0x1, y = 0x2;
x | y ==> 0x3
[Note: operator | can be overloaded for class/struct according to your need.]
| is a bitwise or. It toggles the bits on (1 instead of 0) if one OR the other of the same bit in either integer is on.
|| is the logical or. It returns true if one OR the other are true.
OK, here's why you use a bitwise or, or see them used, in this sort of situation.
Often times, those variables are flags that are used to pack multiple pieces of data into one char
If cSetWatchDogUnit and
cSetTriggerSignal
have non-overlapping bits (imagine cSetWatchDogUnit = 1 << 0 and cSetTriggerSignal = 1 << 1 you can check later to see if they are set with a bitwise and, like this contrived example:
if cData & cSetWatchDogUnit
do something
if cData & cSetTriggerSignal
do something else
The whole time, both of these flags can be packed into and passed around in a single char. That way, you don't end up passing an array of bools, you can add new constants cSetSomeOtherDamnfoolThing = 1 << 2 and you can refer to flags as variables in your code.

C++ bitfield testing

Is there a more compact way of comparing my bits than this (the only way I know):
#define BIT1 1
#define BIT2 2
#define BIT3 4
#define BIT4 8
#define BIT5 16
#define BIT6 32
// I declare this somewhere in a structure
unsigned char bits: 6;
// I want all of them to be 0 at first (000000)
bits = 0;
/* I do some bite setting here */
// I only want to know if the state of my bits == 000000
if(bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))
{
// All kinds of nasty stuff
}
I thought maybe something in the lines of bits & 0x00 == 0x00
If you want compact (as indicated in your comment) rather than fast, why not do something like:
#define BIT1 0x01
#define BIT2 0x02
#define BIT3 0x04
#define BIT4 0x08
#define BIT5 0x10
#define BIT6 0x20
#define BITS1THRU4 (BIT1|BIT2|BIT3|BIT4)
// or #define BITS1THRU6 0x0f
// I declare this somewhere in a structure
unsigned char bits: 6;
// I want all of them to be 0 at first (000000)
bits = 0;
/* I do some bit setting here */
// I only want to know if the state of my first four bits == 0000
if(bits & BITS1THRU4 == 0) ...
It probably won't be any faster since your original code would have been turned into that constant anyway but it may be more readable (which is often a good reason to do it).
If you have a need for other variations, just define them. If there's too many of them (63 defines, if you use them all, may be getting a bit on the high side), I'd start thinking about another solution.
But, to be honest, unless you're going to use more meaningful names for the defines, I'd just ditch them. The name BIT3 really adds nothing to 0x04 to those that understand bit patterns. If it was something like UART_READ_READY_BIT, that would be fine but what you have is only slightly better than:
#define THREE 3
(no offence intended, I'm just pointing out my views). I'd just work out the bit patterns and put them straight in the code (bits 1 thru 6 in your case being 0x3f).
And, just as an aside, for you particular case, I think bits will only be those six bits anyway so you may find it's enough to compare it to 0 (with no bit masking). I've left in the bit masking method in case you wanted a mode general solution for checking specific bits.
if( ~bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))
And about speed (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) is actualy compiled as constant and there are only few operation (like 2) for this if - one NOR and one compare (i am not sure if x386 supprts NOR, but i think it does)
if I read your condition right (with corrected parentheses, as per #user547710), you check if all your bits are set, rather than zero.
Anyway, you can define a mask with bits 1-6 set more compactly by (1u << 6) - 1. This is compile-time constant expression, so you need not to worry about extra computing time. I'd do:
const unsigned char bitmask6 = 1u << 6) - 1;
if ((bits & bitmask6) == bitmask6)
Though this is just a note,
operator == has higher precedence than &,
the logical-and should be parenthesized as:
if((a & b) == c)
I interpreted that this is the intention of the questioner.
(I think this should be posted as just a comment,
but it seems that I can't post a comment)

selective access to bits on datatypes with C++

I'm using C++ for hardware-based model design with SystemC. SystemC as a C++ extension introduces specific datatypes useful for signal and byte descriptions.
How can I access the first bits of a datatype in general, like:
sc_bv<16> R0;
or access the first four bits of tmp.
int my_array[42];
int tmp = my_array[1];
sc_bv is a bit-vector data-type, that's storing binary sequences. Now I want the first four bits of that data-type e. g.. My background is C# and Java, therefore I miss some of the OOP and Reflexion based API constructs in general. I need to perform conversion on this low-level stuff. Useful introductory stuff would help a lot.
Thanks :),
wishi
For sc_bv, you can use the indexing operator []
For the int, just use normal bitwise operations with constants, e.g. the least significant bit in tmp is tmp & 1
I can't really speak for SystemC (sounds interesting though). In normal C you'd read out the lower four bits with a mask like so:
temp = R0 & 0xf;
and write into only the lower four bits (assuming a 32-bit register, and temp<16) like so:
R0 = (R0 & 0xfffffff0) | temp;
To access the first four (i assume you mean four highest bits) bits of tmp (ie to get their values) you use bit masks. So if you want to know if for example the second bit is set you do the following:
int second_bit = (tmp & 0x4000000) >> 30;
now second_bit is 1 if the bit is set and zero otherwise. The idea behind this is the following:
Imagine tmp is (in binary)
1101 0000 0000 0000 0000 0000 0000 0000
Now you use bitwise AND ( the & ) with the following value
0100 0000 0000 0000 0000 0000 0000 0000 // which is 0x40000000 in hex
ANDing produces a 1 on the given bit if and only if both operands have corresponding bits set (they are both 1). So the result will be:
0100 0000 0000 0000 0000 0000 0000 0000
Then you shift this 30 bits to the right, which makes it be:
0000 0000 0000 0000 0000 0000 0000 0001 \\ which is 1
Note that if the original value had the tested bit zero, the result would be zero.
This way you can test any bit you like, you just need to provide correct mask. Note that i assumed here that int is 32bits wide, which should be true in most cases.
You will have to know a bit more about sc_bv to amke sure you get the right information. Also, when you say the "first four bytes" I assume you mean the "first four bits." However, that is misleading as well, because you really want to delineate between the low-order or high-order bits.
In any event, you use the C bitwise operators for this kind of thing. However, you will need to know the size of the integer values AND the "endian-ness" of the runtime architecture to get that right.
But, if you REALLY want just the first four bits, then you would do something like this...
inline unsigned char
first_4_bits(void const * ptr)
{
return (*reinterpret_cast<unsigned char const *>(ptr) & 0xf0) >> 4;
}
and that will grab the very first 4 bits of what it being pointed at. So, if the first byte pointed-to is 0x38, then this function will return the first 4 bits, so the result will be 3.