I am getting an error message about an impossible constraint using an 8-bit typed constant that I flag with constraint "M"
in my inline assembly code for AVR 8-bit micro-controllers such as ATtiny1634 or ATmega328:
static const uint8_t tail_mask = (uint8_t)((rx1::queue_length-1) << \
rx1::queue_length_bits) & 0xFF;
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
warning: asm operand 1 probably doesn't match constraints
Here rx1
is a class name and both queue_length
and queue_length_bits
are static const uint8_t
class constants. I can use "O"
, "N"
, no way. Using static
, int8_t
or not makes no difference.
If I replace the static const uint8_t
definition above with a #define
, the error message vanishes!
#define tail_mask ((rx1::queue_length-1) << rx1::queue_length_bits)
asm(
...
"andi r30, %0\n\t"
...
:
: "M" (tail_mask)
);
Compiles fine!
That bugs me. Why does using an enforced 8-bit unsigned constant produce an error message over a constraint that forces it to be... an 8-bit unsigned constant?
For the record I'm using avr-gcc
version 7.1.0.
The value passed to the constraint should probably be a 32 bit integer here. Which is what you get when you use the #define as it gets promoted to the expected type silently. Likewise using int or unsigned for your tail_mask value will be ok. Weird thing is I went through several versions of the documentation but found no trace of evidence that the M constraint argument cannot be an uint8_t or similar.