The |= is called the “bitwise-OR assignment operator”. Doing this:

x |= y;

is the same as the following:

x = x | y;

Both expressions do a bitwise OR of the values of x and y, then store the result in x.

What is a bitwise OR? That means each bit of both x and y are independently processed according to this rule: if either or both bits are 1, the result is 1, but if both bits are 0, the result is 0.

The expression like (1<<INT0) is called a left-shift. It literally causes the bits in the left operand to be shifted left by the count specified by the right operand. Because the computer represents all numbers internally using binary, doing (1<<A) is the same as raising 2 to the A power. For example:

1 << 0 == 1

1 << 1 == 2

1 << 2 == 4

…

1 << 8 == 256

etc

This might make more sense if we express everything in binary, as is now supported by Arduino:

1 << 3 == B1000

So, when I look in various header files, I find:

#define INT0 6

Now let us consider what happens when you do: GICR |= (1<<INT0). Suppose the current value stored in GICR (in binary) is 00000011. The value of (1<<INT0) is (1<<6), which in binary is 01000000. So when you do a bitwise or of 00000011 and 01000000, you get: 01000011. Then this value is stored in GICR. So the net result is that you have made sure that the given bit is set to 1 inside GICR.

So now, the other part of your question: how do you turn that bit back off? To do this, we need to introduce 2 more operators: bitwise AND, and bitwise NOT (also known as one’s complement). The expression

x &= y;

is the same as:

x = x & y;

In both cases, a given bit in both x and y must be 1 for a 1 to end up being stored back in x. For example, expressed in binary, 00001111 & 01010101 == 00000101.

The bitwise NOT operator is a tilde character ‘~’. It is a unary operator, meaning it operates only a single value that follows it. In binary, the value of ~01000000 == 10111111. So, to answer your question, the way to turn off a bit would be something like:

GICR &= ~(1<<INT0);

Let’s see how this works: Suppose that GICR is 01000011, because you have already set the bit, and now you want to turn that bit back off. The value of (1<<INT0), as we have already seen, is 01000000. So the value of ~(1<<INT0) is 10111111. Then when we AND 01000011 with 10111111, only the bits that are 1 in both will be 1 in the result, which is 00000011.

I hope this helps explain the bitwise operators in C++.