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

How to get the C-compiler to use RLC and ACC.x

Hello,

I would like to know if there's any way I can write C code that will use the assembly instructions RLC and ACC.x efficiently. I would like to some C code that will result in:

MOV A,byBuffer
MOV c,bInput
RLC A
MOV byBuffer,A

The closest I could get was this:

byBuffer=(byBuffer<<1)&bInput;

Which results in:

MOV A,byBuffer
ADD A,ACC
MOV R7,A
MOV C,bInput
CLR A
RLC A
ANL A,R7
MOV byBuffer,A

The same thing happens when I want to use a specific bit from a byte. I have never seen the C-compiler use the ACC.x instruction. It uses solutions like this:

MOV A,R6
MOV R0,AR5
INC R0
SJMP ?C0078
?C0077:
CLR C
RLC A
?C0078:
DJNZ R0,?C0077

Any ideas ????

  • Sorry, forgot to use the pre and /pre....

    //--------------------------------------//

    Hello,

    I would like to know if there's any way I can write C code that will use the assembly instructions RLC and ACC.x efficiently. I would like to some C code that will result in:

    MOV A,byBuffer
    MOV c,bInput
    RLC A
    MOV byBuffer,A
    
    The closest I could get was this:
    byBuffer=(byBuffer<<1)&bInput;
    
    Which results in:
    MOV A,byBuffer
    ADD A,ACC
    MOV R7,A
    MOV C,bInput
    CLR A
    RLC A
    ANL A,R7
    MOV byBuffer,A
    
    The same thing happens when I want to use a specific bit from a byte. I have never seen the C-compiler use the ACC.x instruction. It uses solutions like this:
    MOV A,R6
    MOV R0,AR5
    INC R0
    SJMP ?C0078
    ?C0077:
    CLR C
    RLC A
    ?C0078:
    DJNZ R0,?C0077
    
    Any ideas ????

  • I don't think that it is quite what you are looking for, but there are a number of intrinsic functions provided by Keil and detailed in the C51 Compiler Manual. Most of these intrinsic functions roll a 1, 2 or 4-byte variable n places left or right. Although not perfect, the code for 1 and 2 byte variables is put in-line (rather than a function call) and they make use of RLC type instructions so that they are reasonably fast when shifting by a small number of bits.

    In spite of the claims of the manual, the rolls for 4-byte variables are actually implemented by library calls. Also, if I recall correctly from the last time that I looked, the compiler always codes a loop even when the roll is know to be just one bit.

    For a faster way to roll long variables, see: http://www.keil.com/forum/docs/thread1252.asp

    C can access any bit of a variable by various means. See http://www.keil.com/forum/docs/thread554.asp for some examples The most portable method it to use masks, but I don't think that that will generate an ACC.x type reference. The most obvious method is to use a structure containing fields with a width of just one bit, this will cause ACC.x type instructions to be generated, but Keil does not seem to make very efficient use of them (see http://www.keil.com/forum/docs/thread1291.asp ).

    In the end, if there are just a few very specific functions that you want to perform then your best bet is going to be to write an assembly language sub-routine that you can call from a C function.

  • "I would like to know if there's any way I can write C code that will use the assembly instructions RLC and ACC.x efficiently"

    No 'C' compiler will guarantee to generate any specific sequence of machine instructions from any specific source line.
    That's the point of a high-level language: it removes the need to worry about all that detail, thus improving programmer productivity. Of course, there's no such thing as a free lunch, and the price you pay is the loss of control of the generated machine code - and possibly some loss of efficiency (although modern optimising compilers are pretty good these days).

    If the precise sequence of machine instructions is really important to your application (eg, for timing), you need to write it in assembler.

  • First of all a thanks to Graham for the suggestions, they were very helpfull.

    "Of course, there's no such thing as a free lunch, and the price you pay is the loss of control of the generated machine code"

    Agree, but you never lose complete control. The generated code changes as you change your source-code. When I use nested ifs in stead of cases my source may be less (or more) efficient. Therefore I can influence the generated source. Maybe I'll better change my question to this:

    Are there any C-constructions (or macros) that are known to use RLC and Acc.x ??

  • "Are there any C-constructions (or macros) that are known to use RLC and Acc.x??"

    I think that goes back to my original comment:

    No 'C' compiler will guarantee to generate any specific sequence of machine instructions from any specific source line.

  • First of all, your C code fragment doesn't do what the ASM did. The truly equivalent C fragment would have been:

      byBuffer=(byBuffer<<1) | bInput;
    

    Note the '|' instead of '&' before bInput.

    Anyway: your original assembly isn't picture-perfect, either, so there's not much reason that the C compiler should generate that for any given piece of C code.

      MOV	A, byBuffer
      RL	A
      MOV	ACC.7, bInput
      MOV	byBuffer, A
    

    would have been better, because it doesn't pollute whatever
    was in the carry bit before.