-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello all!
I encountered during my project a strange behaviour of the above gcc
version.
Information to the tool chain:
- ------------------------------
msp430-gcc version 3.2.3
OS: Windows XP Professional SP2
MCU: MSP430F149
Commandline: msp430-gcc -mmcu=msp430x149 -g -O3 -Wall
(Please crosscheck with the emails under the subject
"Something strange with multiplication of constant byte numbers")
october 2004
The problem is, that the code generation is incomplete for the
calculation of constant * byte.
The code section is:
- --------------------
/* Calculation / Code generation problem */
/* calculated result is 63936 (-1600) instead of 24000 */
#define MACRO 240U
int Test (void)
{
~ extern unsigned short u16Result;
~ extern unsigned char u8Value;
~ u16Result = MACRO * u8Value;
~ return (int)u16Result;
}
My assumption is, that the calculation should have
been (written in C for better understanding):
u16Result = u8Value * 256 - u8Value * 16;
In reality, the generated code shows only the right
side of the operation. By this, the final result
of the operation is -u8Value*16.
Assembly output:
- ----------------
/***********************
~ * Function `Test'
~ ***********************/
Test:
.stabn 68,0,4,.LM1-Test
.LM1:
/* prologue: frame size = 0 */
.L__FrameSize_Test=0x0
.L__FrameOffset_Test=0x0
/* prologue end (size=0) */
.LBB2:
.stabn 68,0,8,.LM2-Test
.LM2:
mov.b &u8Value, r15 ; 10 zero_extendqihi2/2 [length = 2]
rla r15 ; 11 *ashlhi3_1/1 [length = 1]
rla r15 ; 12 *ashlhi3_1/1 [length = 1]
rla r15 ; 13 *ashlhi3_1/1 [length = 1]
rla r15 ; 14 *ashlhi3_1/1 [length = 1]
inv r15 ; 15 *one_cmplhi2_2/1 [length = 1]
add #llo(1), r15 ; 16 *addhi3_3/7 [length = 1]
mov r15, &u16Result ; 17 *movhi3/1 [length = 2]
.stabn 68,0,11,.LM3-Test
.LM3:
.LBE2:
.stabn 68,0,12,.LM4-Test
.LM4:
ret
This behaviour was checked with several values
which I expect to use the same optimized calculation
path (not needing the hardware multiplier). The
effect was detected with values 240 (256 - 16),
224 (256 - 32) and values very close to them.
Assumption: Because the shifting is faster than
using the hardware multiplier in some cases, the
calculation is made for special values with those
operations. But the final step seems to be missing.
I haven't found anything for the multiplication
of the u8 with 256 (simple move to the highbyte of
the result) and the subtraction of the calculated
result from this value.
Preprocessed output:
- --------------------
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "test.c"
int Test (void)
{
~ extern unsigned short u16Result;
~ extern unsigned char u8Value;
~ u16Result = 240U * u8Value;
~ return (int)u16Result;
}
Assembly output:
- ----------------
/***********************
~ * Function `Test'
~ ***********************/
Test:
.stabn 68,0,4,.LM1-Test
.LM1:
/* prologue: frame size = 0 */
.L__FrameSize_Test=0x0
.L__FrameOffset_Test=0x0
/* prologue end (size=0) */
.LBB2:
.stabn 68,0,8,.LM2-Test
.LM2:
mov.b &u8Value, r15 ; 10 zero_extendqihi2/2 [length = 2]
rla r15 ; 11 *ashlhi3_1/1 [length = 1]
rla r15 ; 12 *ashlhi3_1/1 [length = 1]
rla r15 ; 13 *ashlhi3_1/1 [length = 1]
rla r15 ; 14 *ashlhi3_1/1 [length = 1]
inv r15 ; 15 *one_cmplhi2_2/1 [length = 1]
add #llo(1), r15 ; 16 *addhi3_3/7 [length = 1]
mov r15, &u16Result ; 17 *movhi3/1 [length = 2]
.stabn 68,0,11,.LM3-Test
.LM3:
.LBE2:
.stabn 68,0,12,.LM4-Test
.LM4:
ret
Robert Dominicus-Schleutermann
- --
Robert Dominicus-Schleutermann Telefon : +49 36203 96314
Software+Systeme Erfurt GmbH Telefon : +49 36203 96301
Fichtenweg 8 Fax : +49 36203 96333
D-99198 Erfurt-Kerspleben
eMail: mailto:[email protected]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFC6iQ77kPn7znKZuYRArY8AJ0Z+YJ9m3acyRAohcm56Af1/yjE5QCeIk7U
m2q+w8DPhZucZWe82gSEdkI=
=3+YZ
-----END PGP SIGNATURE-----