How can I force a C function to be called using a JSR or BSR instead of a BRA?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can I force a C function to be called using a JSR or BSR instead of a BRA?

Jump to solution
1,919 Views
zorrotz
Contributor III

I have a C function which is near (in memory) of its caller (another function also in C).

The compiler generates a BRA instruction to do this call, but I need a JSR or BSR (because I need to save the PC in the stack).

How can I do it?

 

Thanks in advance.

Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
1,459 Views
BlackNight
NXP Employee
NXP Employee

Hello,

it would be good to know which compiler is used.

If it is CodeWarrior for S08, have a look at following options:

-OnP          Disable peephole Optimization (-OnP[={<x>}], default: all)
                   -OnP=m Disable peephole JSR to JMP optimization

 

-OnB          Disable Branch optimizer  (-OnP[={<x>}], default: all)
                   -OnB=t Disable Branch tail optimization
                   -OnB=r Disable Branch to RTS optimization
                   -OnB=b Disable Branch JSR to BSR optimization
                   -OnB=a Disable short BRA optimization

 

You might try switching off the whole optimization (-OnP or -OnB) and later refine it (e.g. using -OnP=m).

 

BK

View solution in original post

0 Kudos
Reply
7 Replies
1,459 Views
Jim_P
Contributor III

question

 

is the BRA at the end of the function or procedure that was called with the saving of the PC,   Does the BRA jump to a routine that ends with a RTS.

then what is the problem - - -the stack is keep straight, less CPU cycles are needed

 

Jim P

 

 

0 Kudos
Reply
1,459 Views
kef
Specialist I

Problem is

  • but I need a JSR or BSR (because I need to save the PC in the stack).

though copy4ram2() doesn't access return address on the stack or being affected by BSR->BRA optimization.

0 Kudos
Reply
1,459 Views
Jim_P
Contributor III

Could you give me and example of code that needs the return address on the stack - - - that is effected by the JSR or BSR to BRA

 

 

0 Kudos
Reply
1,460 Views
BlackNight
NXP Employee
NXP Employee

Hello,

it would be good to know which compiler is used.

If it is CodeWarrior for S08, have a look at following options:

-OnP          Disable peephole Optimization (-OnP[={<x>}], default: all)
                   -OnP=m Disable peephole JSR to JMP optimization

 

-OnB          Disable Branch optimizer  (-OnP[={<x>}], default: all)
                   -OnB=t Disable Branch tail optimization
                   -OnB=r Disable Branch to RTS optimization
                   -OnB=b Disable Branch JSR to BSR optimization
                   -OnB=a Disable short BRA optimization

 

You might try switching off the whole optimization (-OnP or -OnB) and later refine it (e.g. using -OnP=m).

 

BK

0 Kudos
Reply
1,459 Views
zorrotz
Contributor III

It is CodeWarrior 6.3 for S08.

 

The option -OnP=m works OK. It disables peephole JSR to JMP optimization and BSR to BRA optimization.

 

Thanks

0 Kudos
Reply
1,459 Views
zorrotz
Contributor III

I have another doubt.

In example 1, why the optimizer only changes the JSR to JMP when copy4ram2() function is called?

And in example 2, why the optimizer doesn't do the change if I include a NOP after calling copy4ram2()?

(see also the note at the end of the post).

 

Thanks

 

 

EXAMPLE 1. copy4ram2() called using JMP.

 

C function:

void March_XA5_allram ()

{

 

  March_XA5_ram4(); // 1/ March X on RAM4 before using as shadow

  

  copy1ram4();              // 2/ copy RAM1 contents into RAM4 

  March_XA5_ram1();     // 3/ March X on RAM1

  copy4ram1();              // 4/ copy RAM 4 contents into RAM1

  copy3ram4();              // 8/ copy RAM3 contents into RAM4

  March_XA5_ram3();     // 9/ March X on RAM3 

  copy4ram3();              // 10/ copy RAM1 contents into RAM4

  copy2ram4();              // 5/ copy RAM2 contents into RAM4

  March_XA5_ram2();     // 6/ March X on RAM2   

  copy4ram2();              // 7/ copy RAM4 contents into RAM2

 

}

 

Compiler generated code:

  169:   

  170:    March_XA5_ram4();                                          // 1/ March X on RAM4 before using as shadow

  0000 cd0000   [6]             JSR   March_XA5_ram4

  171:    

  172:    copy1ram4();                                                   // 2/ copy RAM1 contents into RAM4 

  0003 cd0000   [6]             JSR   copy1ram4

  173:    March_XA5_ram1();                                          // 3/ March X on RAM1

  0006 cd0000   [6]             JSR   March_XA5_ram1

  174:    copy4ram1();                                                   // 4/ copy RAM 4 contents into RAM1

  0009 cd0000   [6]             JSR   copy4ram1

  175:    copy3ram4();                                                   // 8/ copy RAM3 contents into RAM4

  000c cd0000   [6]             JSR   copy3ram4

  176:    March_XA5_ram3();                                          // 9/ March X on RAM3 

  000f cd0000   [6]             JSR   March_XA5_ram3

  177:    copy4ram3();                                                   // 10/ copy RAM1 contents into RAM4

  0012 cd0000   [6]             JSR   copy4ram3

  178:    copy2ram4();                                                   // 5/ copy RAM2 contents into RAM4

  0015 cd0000   [6]             JSR   copy2ram4

  179:    March_XA5_ram2();                                          // 6/ March X on RAM2   

  0018 cd0000   [6]             JSR   March_XA5_ram2

  180:    copy4ram2();                                                   // 7/ copy RAM4 contents into RAM2

  001b cc0000   [4]             JMP   copy4ram2

  181:  

  182:  }

 

EXAMPLE 2. copy4ram2() called using JSR after including a NOP.

 

C function:

void March_XA5_allram ()

{

 

  March_XA5_ram4(); // 1/ March X on RAM4 before using as shadow

  

  copy1ram4();              // 2/ copy RAM1 contents into RAM4 

  March_XA5_ram1();     // 3/ March X on RAM1

  copy4ram1();              // 4/ copy RAM 4 contents into RAM1

  copy3ram4();              // 8/ copy RAM3 contents into RAM4

  March_XA5_ram3();     // 9/ March X on RAM3 

  copy4ram3();              // 10/ copy RAM1 contents into RAM4

  copy2ram4();              // 5/ copy RAM2 contents into RAM4

  March_XA5_ram2();     // 6/ March X on RAM2   

  copy4ram2();              // 7/ copy RAM4 contents into RAM2

asm(nop); 

 

}

 

Compiler generated code:

169:   

  170:    March_XA5_ram4();                                          // 1/ March X on RAM4 before using as shadow

  0000 cd0000   [6]             JSR   March_XA5_ram4

  171:    

  172:    copy1ram4();                                                   // 2/ copy RAM1 contents into RAM4 

  0003 cd0000   [6]             JSR   copy1ram4

  173:    March_XA5_ram1();                                          // 3/ March X on RAM1

  0006 cd0000   [6]             JSR   March_XA5_ram1

  174:    copy4ram1();                                                   // 4/ copy RAM 4 contents into RAM1

  0009 cd0000   [6]             JSR   copy4ram1

  175:    copy3ram4();                                                   // 8/ copy RAM3 contents into RAM4

  000c cd0000   [6]             JSR   copy3ram4

  176:    March_XA5_ram3();                                          // 9/ March X on RAM3 

  000f cd0000   [6]             JSR   March_XA5_ram3

  177:    copy4ram3();                                                   // 10/ copy RAM1 contents into RAM4

  0012 cd0000   [6]             JSR   copy4ram3

  178:    copy2ram4();                                                   // 5/ copy RAM2 contents into RAM4

  0015 cd0000   [6]             JSR   copy2ram4

  179:    March_XA5_ram2();                                          // 6/ March X on RAM2   

  0018 cd0000   [6]             JSR   March_XA5_ram2

  180:    copy4ram2();                                                   // 7/ copy RAM4 contents into RAM2

  001b cd0000   [6]             JSR   copy4ram2

  181:  asm(nop); 

  001e 9d       [1]             NOP  

  182:   

  183:  }

  001f 81       [6]             RTS

 

 

Note that copy4ram2() function is:

void copy4ram2 ()
{

#asm

          clrh
          clrx
loop1:    lda RAM4START,x
          sta RAM2START,x
          aix #1
          cphx #RAMRANGE
          bne loop1

// verify copy has occurred
        
        clrh
        clrx
loop2:  lda RAM4START,x
        cmp RAM2START,x
        bne error
        aix #1
        cphx #RAMRANGE
        bne loop2
 //       STA   _SRS  // Refresh WDOG
        rts
error:  bra error     
       
#endasm 
 
}

 

0 Kudos
Reply
1,459 Views
kef
Specialist I

In case 1) when you need to do last call in your function and immediately exit and 2) when you don't need to push any parameters to the stack: - intead of jsr to subroutine, executing its body, rts back to your function, and then return from your function; you can just jump to calle saving few CPU cycles on extra jsr-rts. Adding nop in your function makes this optimization not possible, since jmp is not jsr and you can't return to finish your routine (nop).

 

0 Kudos
Reply