This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Useless Moves

Is there a way to change the DEFINE statement to get rid of the two useless mov(s)?

C51 COMPILER V6.02, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN .\MAIN.OBJ
COMPILER INVOKED BY: C:\PROGRAM FILES\KEIL\C51\BIN\C51.EXE .\MAIN.C OPTIMIZE(7,SPEED) NOINTPROMOTE MODDP2 DEBUG OBJECTEX
                    -TEND CODE SYMBOLS NOCOND

stmt level    source

   1          typedef unsigned char BYTE;
   2          typedef unsigned int  WORD;
   3          
   4          typedef pdata struct 
   5          {
   6            BYTE PC0           :1;
   7            BYTE PC1           :1;
   8            BYTE nFifoPend     :1; //PC2
   9            BYTE PC3           :1;
  10            BYTE FpgaReset     :1; //PC4
  11            BYTE PC5           :1;
  12            BYTE PC6           :1;
  13            BYTE PC7           :1; 
  14          } CType;
  15          
  16          extern volatile BYTE pdata xOUTC;
  17          
  18          #define IoPins_FpgaReset ( ((CType pdata*)(&xOUTC))->FpgaReset )
  19          
  20          void main(void)
  21          {
  22   1        IoPins_FpgaReset = 1;
  23   1      }
  24          
  25          


             ; FUNCTION main (BEGIN)
                                           ; SOURCE LINE # 20
                                           ; SOURCE LINE # 21
                                           ; SOURCE LINE # 22
0000 7A00        E     MOV     R2,#HIGH xOUTC
0002 7900        E     MOV     R1,#LOW xOUTC
0004 7800        E     MOV     R0,#LOW xOUTC
0006 E2                MOVX    A,@R0
0007 4410              ORL     A,#010H
0009 F2                MOVX    @R0,A
                                           ; SOURCE LINE # 23
000A 22                RET     
             ; FUNCTION main (END)

Parents
  • 1. bit-fields in Keil C (8051's fault) are horribly inefficient.

    2. Pdata still requires two bytes for a pointer when we cannot guarantee that the page (a 256 byte block of xdata) is not currently loaded.

    How does this work for you?

    typedef enum
    {
        PC0        = 1 << 0,
        PC1        = 1 << 1,
        FIFO_PEND  = 1 << 2,
        PC3        = 1 << 3,
        FPGA_RESET = 1 << 4,
        PC5        = 1 << 5,
        PC6        = 1 << 6,
        PC7        = 1 << 7
    } FpgaPortC;
    
    
    typedef unsigned char U8;
    
    // I use 'r_' to indicate some sore of register variable.
    static volatile U8 pdata r_portC _at_ 0x8000; // 0x8000 is a guess.
    
    #ifdef MUST_INLINE
    #define  resetFpga()  do { r_portC |= FPGA_RESET; } while (0)
    #else
        void resetFpga(void) { r_portC |= FPGA_RESET; }
    #endif
    
    void main(void)
    {
        resetFpga();
    
        for (;;);
    }
    
    ;; *** No inlining ***
                 ; FUNCTION resetFpga (BEGIN)
                                               ; SOURCE LINE # 273
                                               ; SOURCE LINE # 274
                                               ; SOURCE LINE # 275
    0000 7800              MOV     R0,#LOW r_portC
    0002 E2                MOVX    A,@R0
    0003 4410              ORL     A,#010H
    0005 F2                MOVX    @R0,A
                                               ; SOURCE LINE # 276
    0006 22                RET     
                 ; FUNCTION resetFpga (END)
    
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 279
                                               ; SOURCE LINE # 280
                                               ; SOURCE LINE # 281
    0000 120000      R     LCALL   resetFpga
                                               ; SOURCE LINE # 283
    0003         ?C0002:
    0003 80FE              SJMP    ?C0002
                 ; FUNCTION main (END)
    
    ;; *** Inlining ***
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 279
                                               ; SOURCE LINE # 280
                                               ; SOURCE LINE # 281
    0000 7800              MOV     R0,#LOW r_portC
    0002 E2                MOVX    A,@R0
    0003 4410              ORL     A,#010H
    0005 F2                MOVX    @R0,A
                                               ; SOURCE LINE # 283
    0006         ?C0004:
    0006 80FE              SJMP    ?C0004
                 ; FUNCTION main (END)
    
    In both cases:
    C51 COMPILER V6.10, COMPILATION OF MODULE UART
    OBJECT MODULE PLACED IN .\a.OBJ
    COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\a.c BROWSE NOINTPROMOTE DEBUG OBJECTEXTEND CODE PAGEWIDTH(132) PAGELENGTH(6600) 
    
    - Mark

Reply
  • 1. bit-fields in Keil C (8051's fault) are horribly inefficient.

    2. Pdata still requires two bytes for a pointer when we cannot guarantee that the page (a 256 byte block of xdata) is not currently loaded.

    How does this work for you?

    typedef enum
    {
        PC0        = 1 << 0,
        PC1        = 1 << 1,
        FIFO_PEND  = 1 << 2,
        PC3        = 1 << 3,
        FPGA_RESET = 1 << 4,
        PC5        = 1 << 5,
        PC6        = 1 << 6,
        PC7        = 1 << 7
    } FpgaPortC;
    
    
    typedef unsigned char U8;
    
    // I use 'r_' to indicate some sore of register variable.
    static volatile U8 pdata r_portC _at_ 0x8000; // 0x8000 is a guess.
    
    #ifdef MUST_INLINE
    #define  resetFpga()  do { r_portC |= FPGA_RESET; } while (0)
    #else
        void resetFpga(void) { r_portC |= FPGA_RESET; }
    #endif
    
    void main(void)
    {
        resetFpga();
    
        for (;;);
    }
    
    ;; *** No inlining ***
                 ; FUNCTION resetFpga (BEGIN)
                                               ; SOURCE LINE # 273
                                               ; SOURCE LINE # 274
                                               ; SOURCE LINE # 275
    0000 7800              MOV     R0,#LOW r_portC
    0002 E2                MOVX    A,@R0
    0003 4410              ORL     A,#010H
    0005 F2                MOVX    @R0,A
                                               ; SOURCE LINE # 276
    0006 22                RET     
                 ; FUNCTION resetFpga (END)
    
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 279
                                               ; SOURCE LINE # 280
                                               ; SOURCE LINE # 281
    0000 120000      R     LCALL   resetFpga
                                               ; SOURCE LINE # 283
    0003         ?C0002:
    0003 80FE              SJMP    ?C0002
                 ; FUNCTION main (END)
    
    ;; *** Inlining ***
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 279
                                               ; SOURCE LINE # 280
                                               ; SOURCE LINE # 281
    0000 7800              MOV     R0,#LOW r_portC
    0002 E2                MOVX    A,@R0
    0003 4410              ORL     A,#010H
    0005 F2                MOVX    @R0,A
                                               ; SOURCE LINE # 283
    0006         ?C0004:
    0006 80FE              SJMP    ?C0004
                 ; FUNCTION main (END)
    
    In both cases:
    C51 COMPILER V6.10, COMPILATION OF MODULE UART
    OBJECT MODULE PLACED IN .\a.OBJ
    COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\a.c BROWSE NOINTPROMOTE DEBUG OBJECTEXTEND CODE PAGEWIDTH(132) PAGELENGTH(6600) 
    
    - Mark

Children