avr-gcc inline asm constraint bug

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
int main()
{
    asm volatile (
    "clr r25\n"
    "ldi r24, %0\n"
    :: "M" ((unsigned char)137)
    );
}

asm.c:4:5: warning: asm operand 0 probably doesn't match constraints
     asm volatile (
     ^
asm.c:4:5: error: impossible constraint in 'asm'

 

Tested with avr-gcc 5.4.0 and 8.4.0.  If I make the constant less than 128, there is no error.  The docs for the "M" constraint say:

8-bit integer constant 0 to 255

https://www.nongnu.org/avr-libc/...

 

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are a few asm operations that only allow 7 bit constants.  Not sure if that is a factor, here.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd say bug.  I suspect -128 would work.

"i" should work as a constraint.

'Tis part of the generic portion,

so I'd expect it to be better tested and

complaints about it more likely to be heard.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

That's a bug for sure, if you cast to any form of char (signed, unsigned or unqualified) this error occurs. If you cast to int types there are no errors.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

"n" works for me.  From gas manual:

 

 

Using "n" instead of "M":

000000b8 <main>:
  b8:	99 27       	eor	r25, r25
  ba:	89 e8       	ldi	r24, 0x89	; 137
  bc:	90 e0       	ldi	r25, 0x00	; 0
  be:	80 e0       	ldi	r24, 0x00	; 0
  c0:	08 95       	ret

 

Last Edited: Wed. Mar 10, 2021 - 01:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

That's a bug for sure, if you cast to any form of char (signed, unsigned or unqualified) this error occurs. If you cast to int types there are no errors.

 

Thanks.  I never would've thought of trying an int cast. That works perfectly, and the 0-255 range constraint gets properly enforced.  If I with 257 I get an error as expedted:

 

asm.c:3:5: warning: asm operand 0 probably doesn't match constraints
     asm volatile (
     ^~~
asm.c:3:5: error: impossible constraint in 'asm'

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

I'd say bug.  I suspect -128 would work.

"i" should work as a constraint.

 

It's a workaround, but if the constant evaluates to >255, the error isn't caught until the assembler stage, making it hard to track back to the C source:

 

# avr-gcc -mmcu=attiny85 asm.c
C:\msys64\tmp\ccVmqeIB.s: Assembler messages:
C:\msys64\tmp\ccVmqeIB.s:22: Warning: constant out of 8-bit range: 256
C:\msys64\tmp\ccVmqeIB.s:22: Error: operand out of range: 256

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW wrote:

 

"n" works for me.  From gas manual:

 

 

Using "n" instead of "M":

000000b8 <main>:
  b8:	99 27       	eor	r25, r25
  ba:	89 e8       	ldi	r24, 0x89	; 137
  bc:	90 e0       	ldi	r25, 0x00	; 0
  be:	80 e0       	ldi	r24, 0x00	; 0
  c0:	08 95       	ret

 

 

I like #4 better.  With "M" and an int16 cast, when the constant evaluates to >255 I get a constraint error as I showed in #6.  With "n" and an int16 cast, I don't get the error until the assembler stage, like in #7.  If I use "n" and an char cast, although it works as desired with values up to 255, if the expression evaluates to >255, the char cast wraps, and I don't get any error indicating the constant was larger than 8 bits.

 

I have no special talents.  I am only passionately curious. - Albert Einstein