Just as the compiler has added custom support for bits, it should also add custom support for function pointers. Here is one idea:
//Saves on storage (1 byte) //Is faster (fixed jump table) //No need to add/remove references in the linker void fn1( void ){}; void fn2( void ){}; void fn3( void ){}; void fn4( void ){}; enumfn MyFnType { fn1, fn2, fn3 }; //must have same signatures MyFnType myFnVar; void FnA(void) { myFnVar = fn1; // do not add fn1 to FnA's call tree myFnVar = fn4; // compiler error } void FnB(void) { (myFnVar)(); // do add fn1,fn2,fn3 to FnB's call tree }
Here is another approach that would work well for me. Just optimize ( *constFnTbl[i] )(<parms>);
// //c code // typedef char (code* PFN)(char); code fnTbl[] = { fn1, fn2, fn3 }; void main( void ) { volatile char i; volatile char x = ( *fnTbl[i] )( 2 ); } // // I would like // main: mov r7,#2 mov a,i mov dptr,#jmpTbl call evalfn mov x,r7 ret jmpTbl: ajmp fn1 ajmp fn2 ajmp fn3 evalfn: lsl a jmp @+dptr // // Current code // 0000 AF00 R MOV R7,i 0002 EF MOV A,R7 0003 25E0 ADD A,ACC 0005 2400 R ADD A,#LOW fnTbl 0007 F582 MOV DPL,A 0009 E4 CLR A 000A 3400 R ADDC A,#HIGH fnTbl 000C F583 MOV DPH,A 000E E4 CLR A 000F 93 MOVC A,@A+DPTR 0010 FE MOV R6,A 0011 7401 MOV A,#01H 0013 93 MOVC A,@A+DPTR 0014 F582 MOV DPL,A 0016 8E83 MOV DPH,R6 0018 7F02 MOV R7,#02H 001A 120000 R LCALL ?C0005 001D 8002 SJMP ?C0006 001F ?C0005: 001F E4 CLR A 0020 73 JMP @A+DPTR 0021 ?C0006: 0021 8F00 R MOV x,R7 ;0023 22 RET ; FUNCTION main (END)