Hi, I think I have found a bug in the way mspgcc generates in-line multiply code when using typecasts. In a particular bit of code, I want to multiply a byte-sized variable with a constant. The result should be 16-bit, since it could well be over 255. I was under the impression that normal C integer promotion would automatically give me 16-bit wide multiplication, but since that failed, I tried typecasting - and that failed too.
In the sample below, m1 is generated as 8-bit. I thought that should be 16-bit, but I am quite happy to believe that 8-bit is the correct code and that my interpretation is wrong. m3 is generated correctly for 16-bit. But m2 should be 16-bit, and yet is generated as 8-bit. Incidently, is the inline multiply code faster than using the hardware multiply? I can see it would be for small constants, but do you switch over automatically for constants that generate larger code? Also, is it not possible to optomise the 7 "rla" instructions as a "swapb" then an "rra" ? The command-line I used was this (although I also tried with optomisation off - it made no difference): msp430-gcc -c -mmcu=msp430x149 -g -O2 -fverbose-asm -Wa,-ahld=test.lst test.c mvh. David /**** test.c ****/ #define scale 122 unsigned int m1(unsigned char b) { // The mult is 8-bit return b*scale; } unsigned int m2(unsigned char b) { // The mult should be 16-bit, but is actually 8-bit return ((unsigned int)b) * scale; } unsigned int m3(unsigned int w) { // The mult is 16-bit return w * scale; } unsigned int m4(unsigned char b) { // The mult is 16-bit unsigned int w = b; return w * scale; } /**** test.lst ****/ 12:test.c **** #define scale 122 13:test.c **** 14:test.c **** unsigned int m1(unsigned char b) { 109 .LM1: 110 /* prologue: frame size = 0 */ 111 .L__FrameSize_m1=0x0 GAS LISTING /cygdrive/d/temp/ccGc8q6D.s page 2 112 .L__FrameOffset_m1=0x0 113 /* prologue end (size=0) */ 15:test.c **** // The mult is 8-bit 16:test.c **** return b*scale; 115 .LM2: 116 0000 4E4F mov.b r15, r14 ; b, b 117 0002 0E5E rla r14 ; b 118 0004 0E5E rla r14 ; b 119 0006 0E5E rla r14 ; b 120 0008 0E5E rla r14 ; b 121 000a 0E5E rla r14 ; b 122 000c 0E5E rla r14 ; b 123 000e 0E5E rla r14 ; b 124 0010 4F5F rla.b r15 ; b 125 0012 4E8F sub.b r15, r14 ; b, b 126 0014 4E8F sub.b r15, r14 ; b, b 127 0016 4E8F sub.b r15, r14 ; b, b 17:test.c **** } 129 .LM3: 130 0018 0F4E mov r14, r15 ; b 131 001a 3041 ret 132 /* epilogue: not required */ 133 /* function m1 size 14 (13) */ 134 .Lfe1: 136 /********* End of function ******/ 137 138 .Lscope0: 140 .p2align 1,0 143 .global m2 145 /*********************** 146 * Function `m2' 147 ***********************/ 148 m2: 18:test.c **** 19:test.c **** unsigned int m2(unsigned char b) { 150 .LM4: 151 /* prologue: frame size = 0 */ 152 .L__FrameSize_m2=0x0 153 .L__FrameOffset_m2=0x0 154 /* prologue end (size=0) */ 20:test.c **** // The mult should be 16-bit, but is actually 8-bit 21:test.c **** return ((unsigned int)b) * scale; 156 .LM5: 157 001c 4E4F mov.b r15, r14 ; b, b 158 001e 0E5E rla r14 ; b 159 0020 0E5E rla r14 ; b 160 0022 0E5E rla r14 ; b 161 0024 0E5E rla r14 ; b 162 0026 0E5E rla r14 ; b 163 0028 0E5E rla r14 ; b 164 002a 0E5E rla r14 ; b 165 002c 4F5F rla.b r15 ; b 166 002e 4E8F sub.b r15, r14 ; b, b 167 0030 4E8F sub.b r15, r14 ; b, b 168 0032 4E8F sub.b r15, r14 ; b, b 22:test.c **** } 170 .LM6: GAS LISTING /cygdrive/d/temp/ccGc8q6D.s page 3 171 0034 0F4E mov r14, r15 ; b 172 0036 3041 ret 173 /* epilogue: not required */ 174 /* function m2 size 14 (13) */ 175 .Lfe2: 177 /********* End of function ******/ 178 179 .Lscope1: 181 .p2align 1,0 184 .global m3 186 /*********************** 187 * Function `m3' 188 ***********************/ 189 m3: 23:test.c **** 24:test.c **** unsigned int m3(unsigned int w) { 191 .LM7: 192 /* prologue: frame size = 0 */ 193 .L__FrameSize_m3=0x0 194 .L__FrameOffset_m3=0x0 195 /* prologue end (size=0) */ 25:test.c **** // The mult is 16-bit 26:test.c **** return w * scale; 197 .LM8: 198 0038 0E4F mov r15, r14 ; w, w 199 003a 0E5E rla r14 ; w 200 003c 0E5E rla r14 ; w 201 003e 0E5E rla r14 ; w 202 0040 0E5E rla r14 ; w 203 0042 0E5E rla r14 ; w 204 0044 0E5E rla r14 ; w 205 0046 0E5E rla r14 ; w 206 0048 0F5F rla r15 ; w 207 004a 0E8F sub r15, r14 ; w, w 208 004c 0E8F sub r15, r14 ; w, w 209 004e 0E8F sub r15, r14 ; w, w 27:test.c **** } 211 .LM9: 212 0050 0F4E mov r14, r15 ; w 213 0052 3041 ret 214 /* epilogue: not required */ 215 /* function m3 size 14 (13) */ 216 .Lfe3: 218 /********* End of function ******/ 219 220 .Lscope2: 222 .p2align 1,0 225 .global m4 227 /*********************** 228 * Function `m4' 229 ***********************/ 230 m4: 28:test.c **** 29:test.c **** unsigned int m4(unsigned char b) { 232 .LM10: 233 /* prologue: frame size = 0 */ 234 .L__FrameSize_m4=0x0 GAS LISTING /cygdrive/d/temp/ccGc8q6D.s page 4 235 .L__FrameOffset_m4=0x0 236 /* prologue end (size=0) */ 237 .LBB2: 30:test.c **** // The mult is 16-bit 31:test.c **** unsigned int w = b; 239 .LM11: 240 0054 4E4F mov.b r15, r14 ; b, w 32:test.c **** return w * scale; 242 .LM12: 243 0056 0F4E mov r14, r15 ; w, w 244 0058 0F5F rla r15 ; w 245 005a 0F5F rla r15 ; w 246 005c 0F5F rla r15 ; w 247 005e 0F5F rla r15 ; w 248 0060 0F5F rla r15 ; w 249 0062 0F5F rla r15 ; w 250 0064 0F5F rla r15 ; w 251 0066 0E5E rla r14 ; w 252 0068 0F8E sub r14, r15 ; w, w 253 006a 0F8E sub r14, r15 ; w, w 254 006c 0F8E sub r14, r15 ; w, w 255 .LBE2: 33:test.c **** } 257 .LM13: 258 006e 3041 ret 259 /* epilogue: not required */ 260 /* function m4 size 14 (13) */ 261 .Lfe4: 263 /********* End of function ******/ 264