[Icc-avr] chars should be converted to ints
inarithmeticexpressions
John Baraclough
j_baraclough at zetnet.co.uk
Tue Mar 27 13:08:30 PST 2007
Whilst I agree with you that the compiler behaviour does not appear
to comply with the C specification, I think your test below is a
little unfair. You will notice some consistency in the listing. In
the first, third and fifth assignments the compiler knows that
register r3 doesn't contain a valid copy of data[1] and loads it
accordingly. However in assignments two and four, it knows that r3
already contains the value of data[1] and thus a load is not required
and a different action is seen.
Having said that, the fact remains that the 8-bit value is shifted
off the end of r3 and lost which shows that the promotion to integer
is not happening. Perhaps Richard would care to comment on that.
Did you try declaring all the variables as globals to force them into
RAM and then look at the results?
Did you try using different indices in the assignments to force the
compiler to reload each time and then look at the results?
Writing bombproof code is always a challenge, and it's useful to
remember the maxim that "assume" will make an "ass" out of "u" and
"me". Assuming that a compiler will promote a variable to the correct
size is one of those mistakes that is easy to make. Indeed, I have
been there quite a few times. It is always good practice to force
data promotion (and of course demotion) by casting whenever it is
required. It shouldn't make the built code any larger and will never
fail to produce the expected results.
All the best for now,
John
At 20:47 27/03/2007, you wrote:
>Content-class: urn:content-classes:message
>Content-Type: multipart/alternative;
> boundary="----_=_NextPart_001_01C770A8.C4DF0291"
>
>Here's a little more info.
>The behavior seems to be a bit inconsistent.
>
>test code:
> char data[8] = { 1, 3, 7, 15, 31, 63, 127, 255 };
> int r1, r2, r3, r4, r5;
>
> r1 = ((data[1] << 8) + data[3]);
> r2 = ((data[1] << 8) + data[3]) * 1;
> r3 = ((data[1] << 8) + data[3]) * 2;
> r4 = ((data[1] << 8) + data[3]) * 14;
> r5 = ((data[1] << 8) + data[3]) + 400;
>
> cprintf("r1 = %d\n", r1);
> etc.
>
>results:
> r1 = 783 // correct: 3 * 256 + 15
> r2 = 15 // wrong
> r3 = 1566 // correct: r1 * 2
> r4 = 210 // wrong
> r5 = 1183 // correct: r1 + 400
>Here's what the compiler creates:
>
> 0040 ; r1 = ((data[1] << 8) + data[3]);
> 0040 2F80 ldd R2,y+7
> 0042 3D80 ldd R3,y+5
> 0044 532D mov R21,R3
> 0046 422D mov R20,R2
> 0048 .dbline 120
> 0048 ; r2 = ((data[1] << 8) + data[3]) * 1;
> 0048 330C lsl R3
> 004A 330C lsl R3
> 004C 330C lsl R3
> 004E 330C lsl R3
> 0050 330C lsl R3
> 0052 330C lsl R3
> 0054 330C lsl R3
> 0056 330C lsl R3
> 0058 320C add R3,R2
> 005A 81E0 ldi R24,1
> 005C 839D mul R24,R3
> 005E 7001 movw R14,R0
> 0060 .dbline 121
> 0060 ; r3 = ((data[1] << 8) + data[3]) * 2;
> 0060 3D80 ldd R3,y+5
> 0062 D32C mov R13,R3
> 0064 C22C mov R12,R2
> 0066 CC0C lsl R12
> 0068 DD1C rol R13
> 006A .dbline 122
> 006A ; r4 = ((data[1] << 8) + data[3]) * 14;
> 006A 330C lsl R3
> 006C 330C lsl R3
> 006E 330C lsl R3
> 0070 330C lsl R3
> 0072 330C lsl R3
> 0074 330C lsl R3
> 0076 330C lsl R3
> 0078 330C lsl R3
> 007A 320C add R3,R2
> 007C 8EE0 ldi R24,14
> 007E 839D mul R24,R3
> 0080 5001 movw R10,R0
> 0082 .dbline 123
> 0082 ; r5 = ((data[1] << 8) + data[3]) + 400;
> 0082 3D80 ldd R3,y+5
> 0084 732D mov R23,R3
> 0086 622D mov R22,R2
> 0088 6057 subi R22,112 ; offset = 400
> 008A 7E4F sbci R23,254
> 008C .dbline 124
>
>Any thoughts, Richard?
>
>Cheers
>Glenn Greig
>Ross Video Limited
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://dragonsgate.net/pipermail/icc-avr/attachments/20070327/76ee901f/attachment.html
More information about the Icc-avr
mailing list