[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] cbr and negative numbers
From: |
Ruud Vlaming |
Subject: |
[avr-gcc-list] cbr and negative numbers |
Date: |
Wed, 10 Sep 2008 15:57:15 +0200 |
User-agent: |
KMail/1.9.1 |
Suppose you compile the (nonsense) code below under
'standard' settings (see below for my settings, but is does
not really matter for now) Then there is no problem.
However, if you activate the 8 bit integer option -mint8
you get an error:
code_Test.s:75: Error: number must be less than 256
void TestCBR(void) __attribute__ ((naked, used));
void TestCBR(void)
{ asm volatile (
"cbr r31, 0xC0 \n\t" /* This value passes */
"cbr r31,%[_A_] \n\t" /* This value passes */
"sbr r31,%[_B_] \n\t" /* This value passes */
"cbr r31,%[_B_] \n\t" /* This may generate an error */
"ret \n\t"
"" ::
[_A_] "i" (0x70),
[_B_] "i" (0xC0)); }
Now, this has nothing to do with lib c (for which mint8 is
discurraged), but with the part that translates the assembler
into opcodes. This is why:
without -mint8 you get
TestCBR:
.LFB11:
.LM7:
/* prologue: frame size=0 */
/* prologue: naked */
/* prologue end (size=0) */
/* #APP */
cbr r31, 0xC0
cbr r31,112
sbr r31,192
cbr r31,192
ret
with -mint8 you get
TestCBR:
.LFB11:
.LM7:
/* prologue: frame size=0 */
/* prologue: naked */
/* prologue end (size=0) */
/* #APP */
cbr r31, 0xC0
cbr r31,112
sbr r31,-64
cbr r31,-64
ret
The negative numbers are ofcourse a direct consequence of the
-mint8 option where -64 equals 192. For most instructions
this is not a problem since -64 can be represented as follows
8 bit: 0xC0
16 bit: 0xFFC0
32 bit: 0xFFFFFFC0
Whatever you take, the last 2 bytes will always be C0.
But the AVR CBR instruction must perform a calculation first
before the opcode can be produced. (CBR is transformed into
an ANDI) Thats why sbr r31,-64 works whereas cbr r31,-64 does
not.
I don't know if this might be called a bug, but it is annoying.
Of course, it is not so difficult to circumvent this problem, but
if you have parametarized assembler (like i have) you cannot be
sure if the problem might occur at some later moment. Or you must
eliminate the CBR instructions all together. It looks like the
CBR is the only instruction suffering this problem.
I think the best solution would be to prohibit the compiler from
emitting negative numbers as arguments, independant if the setting
is -mint8 or not. Positive numbers (or even better: hexadecimal)
would be a lot clearer.
Ruud.
(*) my settings where:
avr-gcc -save-temps -mmcu=attiny861 -Wall -Wno-main -Winline
-Wundef -gdwarf-2 -Os -funsigned-char -fomit-frame-pointer
-fpack-struct -fshort-enums
Btw, i know that -mint8 is an option that not everybody loves,
and some may even go that far as to say it should be prohibited.
In any case, using this option (and a little carefull programming)
can reduce your code by 8%!! I think such an option is an absolute
necessity for anyone working low level. It would of course be better
to have an option which would honnor the bitlengths of the predefined
integers, and still be suppressing 16bit promotion of operators.
Until that day we have to stick with -mint8.
Message not available