What I meant was that the mask would be shifted just one place for each iteration of the loop, whereas shifting the 32 bit ir_code variable would require a loop with LSLF or LSRF as many as 31 times to get 1UL << 31. Also, shifting a 32 bit word requires four byte-wise shifts for each operation.
OP uses a PIC18 device. For the mask method, you would need to initialize
ir_code = 0x00000000; // takes 4 Tcy
mask = 0x80000000; // takes 5 Tcy
and each iteration performs (worse case of 16 1's bits)
ir_code |= mask; // takes 8 Tcy per 1's bit
mask >>= 1; // takes 5 Tcy
for a total of (4+5)+(16*8)+(32*5) = 297 Tcy and 4 additional bytes of RAM for the mask.
For the ir_code shift method, there is no need to initialize ir_code because whatever in ir_code will be shifted out and replaced with new data bits, and each iteration performs
ir_code >>= 1; // takes 5 Tcy
ir_code |= (1UL << 31); // takes 1 Tcy per 1's bit
for a total of (32*5)+(16*1) = 176 Tcy and no additional RAM usage.
Parsing the received bit stream into four bytes would require only a single LSLF or LSRF operation for each iteration, and will result in the four bytes of address and data. That would also only require an 8 bit mask.
With the four individual bytes, the mask method takes
ir_byte = 0x00; // takes 1 Tcy
mask = 0x80; // takes 2 Tcy
and each iteration performs (worse case of four 1's bits per byte)
ir_byte |= mask; // takes 2 Tcy per 1's bit
mask >>= 1; // takes 2 Tcy
for a total of (1+2)+(4*2)+(8*2) = 27 Tcy per byte with four 1's bit, or (4*27) = 108 Tcy for four bytes.
The ir_byte shift method takes
ir_byte >>= 1; // takes 2 Tcy
ir_byte |= 0x80; // takes 1 Tcy per 1's bit
for a total of (8*2)+(4*1) = 20 Tcy per byte with four 1's bit, or (4*20) = 80 Tcy for four bytes.
However, this method may take more program memory; indirect addressing with pointer might reduce it.
You could also just conditionally OR the ir_code variable with 0x800000 when a "1" is detected, and shift right once for each operation.
That is what my code in Post #242 is doing.