Topic : Compiler uses 16bit operation for unsigned char

Forum : ST7/STM8

Original Post
Post Information Post
April 27, 2010 - 3:52pm
Guest

Hi,

I am migrating from Cosmic to Raisonance C-compiler. But my program is about 40% slower when using the Raisonance compiler. The reason is, that Raisonance uses "CALL ?C?cps1616" for some of my unsigned char comparisons. This only happens, when numbers higher than 127 are used inside an IF-statement. Up to 127, Raisonance uses fast 8bit comparison. The Cosmic compiler always uses the fast 8bit comparison.
Is there a way to change the behaviour of the Raisonance compiler to improve performance? Or is there a special reason for that?

Here is an excerpt of the code, showing an 8bit comparison (C-Code) that is translated to an 16bit operation in assembler:

              ; SOURCE LINE # 7:   if(temp > (unsigned char)128)
0000 3F05       F                      CLR    ?CH
0002 90BF06     F                      LD     ?CL,Y
0005 5F                                CLR    X
0006 A680                              LD     A,#080H
0008 CD0000     F                      CALL   ?C?cps1616
000B 24F3                              JRUGE  ?FOR_0001

Any help is appreciated,
Mark

Complete listing, using a value of 127:

RCSTM8 COMPILER V2.26.09.317,  MAIN               04/27/10  14:28:20

QCW(0x00143F20)

RCSTM8 COMPILER V2.26.09.317, COMPILATION OF MODULE MAIN      
OBJECT MODULE PLACED IN C:\Programme\Raisonance\Ride\Examples\main.obj
COMPILER INVOKED BY: QUIET GENERATEDEPFILE CODE DB OJ(C:\Programme\Raisonance\Ride\Examples\main.obj) PR(C:\Programme\Raisonance\Ride\Examples\main.lst) PIN(C:\Programme\Raisonance\Ride\Inc;C:\Programme\Raisonance\Ride\Inc\ST7) O(3,SIZE) NOINITSTATICVAR SMALLOBJECT ET(INT) 

stmt level    source
   1          #pragma preprint
   2          
   3          void main(){
   4   1         unsigned char temp;
   5   1      
   6   1         for(;;){
   7   2            if(temp > (unsigned char)127){
   8   3               temp++;
   9   3            }
  10   2         }
  11   1      }
RCSTM8 COMPILER V2.26.09.317
ASSEMBLY LISTING OF GENERATED OBJECT CODE

              ; FUNCTION main (BEGIN)
              ; Y is assigned to temp
0000         ?FOR_0001:
              ; SOURCE LINE # 7 
0000 90A37F                            CP     Y,#07FH
0003 23FB                              JRULE  ?FOR_0001
              ; SOURCE LINE # 8 
0005 905C                              INC    Y
              ; SOURCE LINE # 6 
0007 20F7                              JRA    ?FOR_0001
              ; temp         unsigned char  (size=1). Automatic variable  in PAGE0

              ; FUNCTION main (END)

RCSTM8 COMPILER V2.26.09.317

MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =      9    ----
   CONSTANT SIZE    =   ----    ----
   DATA SIZE        =   ----    ----
   PAGE0 SIZE       =   ----       1
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.

RCSTM8 COMPILATION COMPLETE.  0 WARNING,  0 ERROR

Complete listing, but this time a value of 128 is used:

RCSTM8 COMPILER V2.26.09.317,  MAIN               04/27/10  14:29:47

QCW(0x00143F20)

RCSTM8 COMPILER V2.26.09.317, COMPILATION OF MODULE MAIN      
OBJECT MODULE PLACED IN C:\Programme\Raisonance\Ride\Examples\main.obj
COMPILER INVOKED BY: QUIET GENERATEDEPFILE CODE DB OJ(C:\Programme\Raisonance\Ride\Examples\main.obj) PR(C:\Programme\Raisonance\Ride\Examples\main.lst) PIN(C:\Programme\Raisonance\Ride\Inc;C:\Programme\Raisonance\Ride\Inc\ST7) O(3,SIZE) NOINITSTATICVAR SMALLOBJECT ET(INT) 

stmt level    source
   1          #pragma preprint
   2          
   3          void main(){
   4   1         unsigned char temp;
   5   1      
   6   1         for(;;){
   7   2            if(temp > (unsigned char)128){
   8   3               temp++;
   9   3            }
  10   2         }
  11   1      }
RCSTM8 COMPILER V2.26.09.317
ASSEMBLY LISTING OF GENERATED OBJECT CODE

              ; FUNCTION main (BEGIN)
              ; Y is assigned to temp
0000         ?FOR_0001:
              ; SOURCE LINE # 7 
0000 3F05       F                      CLR    ?CH
0002 90BF06     F                      LD     ?CL,Y
0005 5F                                CLR    X
0006 A680                              LD     A,#080H
0008 CD0000     F                      CALL   ?C?cps1616
000B 24F3                              JRUGE  ?FOR_0001
              ; SOURCE LINE # 8 
000D 905C                              INC    Y
              ; SOURCE LINE # 6 
000F 20EF                              JRA    ?FOR_0001
              ; temp         unsigned char  (size=1). Automatic variable  in PAGE0

              ; FUNCTION main (END)

RCSTM8 COMPILER V2.26.09.317

MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =     17    ----
   CONSTANT SIZE    =   ----    ----
   DATA SIZE        =   ----    ----
   PAGE0 SIZE       =   ----       1
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.

RCSTM8 COMPILATION COMPLETE.  0 WARNING,  0 ERROR

and finally, this is an excerpt of the code, that is created by Cosmic-Compiler for a value of 128:

  51  0000               _main:
  54  0000               L72:
  55                     ; 5       if(temp > (unsigned char)128){
  57  0000 b6ff             ld   a,_main$L-1
  58  0002 a181             cp   a,#129
  59  0004 25fa             jrult   L72
  60                     ; 6          temp++;
  62  0006 3cff             inc   _main$L-1
  63  0008 20f6             jra   L72
  75                        xdef   _main
  94                        end
Replies
Post Information Post
+1
0
-1
April 27, 2010 - 5:27pm
Raisonance Support Team

Hi Markus,

Thanks for this detailed report. We succesfully reproduced the problem in our Labs.

The problem lies in our optimizer:
- In the comparison "(temp > (unsigned char)128)" both operands must be implicitly cast to "int" type, as the C language never performs byte-size arithmetic.
- The optimizer is responsible for recognizing cases where both sides of a binary operator (such as your ">" comparison operator) can be safely handled as chars, and will generate code that only handles such types.
- In your example, our optimizer does not properly recognize that both sides of the comparison can be reduced to "unsigned char", hence keeps the int type for the comparison, which leads to bigger ansd slower code.

We will look further into this problem and will come back to you.
Sorry for the inconvenience.

Regards,
Bruno

+1
0
-1
March 2, 2012 - 4:13pm
Raisonance Support Team

Hi Mark,

[Edit] Your report was made on an old version of our compiler (November 2009).

With the latest compiler, using the same settings we found that the code is now *much* shorter:

             ; FUNCTION main (BEGIN)
             ; Y is assigned to temp
0000         ?FOR_0001:
             ; SOURCE LINE # 8
0000 90A37F                            CP     Y,#07FH
0003 23FB                              JRULE  ?FOR_0001
             ; SOURCE LINE # 10
0005 905C                              INC    Y
             ; SOURCE LINE # 6
0007 20F7                              JRA    ?FOR_0001

Thanks again for raising this problem. You should now switch to a more recent version of our compiler in order to get the best performance.

Best Regards,
Regards,