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




Reply via email to