Search code examples
cassemblyavravr-gcc

Balancing branches in regard to cycles used


I have a loop with several conditional branches in it. The loop is supposed to always run the same amount of cycles no matter what branches are taken.

To achieve this I filled the shorter branches with NOPs (using asm("nop")) until they were of equal length to the longer branches. This achieved what I wanted.

Now I have a lot more branches and want to automatically balance the branches. I am compiling with avr-gcc.

Is there a way to do this?

As requested: I am using an ATmega 1284p and avr-gcc for my implementation.


Solution

  • Well you didn't specify whether you are coding in asm or in c, since you use branches but you call "asm()"... If using C, you can call millis() at the beginning of your loop, and call it at the end too. You have to calculate the maximum duration of the loop. So subtract the two millis values and compare the difference with the maximum duration of the loop. Yea lilbit confusing, here the code:

    #define MAX_DURATION 1000 //let's say 1 second, but you should calculate it
    while(yourcondition) {
      temp1 = millis();
      //do your branches
    
      temp2 = millis();
      delay(MAX_DURATION-(temp2-temp1));
    }
    

    While if you are coding in asm, you have at first to disable interrupts in order not to have longer loops. Then you can setup a 16bit timer, if your processor has any, with the greatest prescaler and then checking the timer value instead of millis and make a delay function, easily done as:

    delay: ;put the millisecond to wait in r17:r16
      ldi r18, 200
      ldi r19, 26 ;200*26* (3 cicles each little loop) = 1 millisecond of delay with a 16MHz oscillator
      mov r20, r17
      delay_loop:
           dec r19
           brne delay_loop
          ldi r19, 26
          dec r18
          brne delay_loop
         ldi r18, 200
         dec r17
         brne delay_loop
        mov r17, r20
        dec r16
        brne delay_loop
      ret
    

    Hoping that your instrunction set is similar to mine. Next time specify what code are you using and What processor are you targeting