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

efficient packing

First, I am using 7.5 so it is an old compiler, but that is the way it is.

I have a number of bit variables that I am trying to pack into a byte. they are scattered all across the bit area

volatile bit var1;
volatile bit var2;
volatile bit var3;

char result;

The compiler won't let me do

          result=   (var1 <<1) | (var2 <<2) | (var3 <<4);

the only way I have been able to get this to work is

           result= var1;
           result= ((((result << 1) | var2)<<1) | var3)<<1);

This results in very inefficient code
           mov a,result
           mov  r7,a

           mov   c,v2
           clr  a
           rlc  A
           orl  A,R7;
           add  A,ACC
           mov  a,r7

           mov  c,var3
           rlc  A
           orl  A,R7
           add  A,ACC
           mov  a,r7
etc.
as compared to:

           mov A,result
           mov c,v2
           rlc a
           mov  c,v3
           rlc a

would be much better.  Does anyone know how this might be forced in C, without resorting to assembly?

I'm wondering if because the ACC and PSW are evenly divisible by 8, whether or not you can use
those and explicitly use the _crol_ intrinsic to accomplish this.  I have not had any luck so far.

In this case memory efficiency is more important than speed.


Parents Reply Children
  • For it to be a bug, it has to be doing something unintended. Unless you can find a document stating exactly what is intended you might find it very difficult convincing anyone else that it might be.

  • Well, the documentation claims:
    http://www.keil.com/support/man/docs/c51/c51_le_bdata.htm

    The bdata memory type may be used to declare variables only. You may not declare bdata
    functions. This memory is directly accessed using 8-bit addresses and is the on-chip
    bit-addressable RAM of the 8051. Variables declared with the bdata type are bit
    addressable and may be read and written using bit instructions.
    


    And then links to:
    http://www.keil.com/support/man/docs/c51/c51_le_bitaddrobj.htm
    which further claims:

    Bit-addressable objects are objects that may be addressed as words or as bits.
    

    This all breaks down, if the compiler doesn't understand the aliasing between the words and the bits, forcing the program to either only use word addressing or bit addressing.

  • There are two items at issue.

    1. the order of volatile and bdata. volatile bdata char variable should work.
    because volatile bit variable works.
    So in my book that inconstancy is a bug.

    2. The compiler fails to pick the bdata up, after modification, which is what Per is talking about. Again, the compiler has a bug in it, because logically it should be aware of the bits and where they are aliased to and understand that if an aliased bit is in the bdata area, and that byte was loaded into a register, then it needs to be reloaded again.
    I fully well expected that the compiler would pass the modified value to the subsequent function call, not that it would pass the original value to the function call.

    It may not be a programming bug, but it certainly is a LOGICAL bug, as is the first item.

    Inconsistencies in operation indicate a bug.
    It is quite probable, that the parser has a issue in parsing that line.

    Whatever the case, I have managed to force the to do what I wanted it to. But having to change the order of volatile doesn't make sense.

  • " the order of volatile and bdata. volatile bdata char variable should work.
    because volatile bit variable works."

    Note that bit is a data type, similar to char, int, float.
    While bdata is a storage attribute. And standard C doesn't have bdata, idata, far, near, ... that different platforms might need.

    But it would be interesting to know what the compiler thinks about

    static volatile bit x;
    


    or

    volatile static bit x;
    


    or

    static bit volatile x;
    

  • why not 'pack' in the definitions

    u8 bdata packer
    sbit packbit1 packer^1

    the above may be slightly wrong in the format I have not used the '51 for a while, but do remember using the above technique

    Erik