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.
已解决! 转到解答。
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
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
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
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
}
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).