Date : Sun, 17 Jul 1994 19:40:54 EST
From : Stephen Quan <quan@...>
Subject: 256 branches in C.
Hi everyone. I have two parallel BBC emulators in the works and both
of the are finally getting some perfomance (I switch C compilers :-).
One thing is getting me down, however, which nearly makes me opt for
assembly is the difficulty of creating 256-branch instructions.
Currently, I have :
switch (opcode)
{
case 0x00 : ....
case 0x01 : ....
case 0x02 : ....
....
case 0xff : ....
default :
break;
}
and unless if you have the optimiser on, you will get terrible code from
the above. ie. the assembly language looked something like :
LDA opcode
CMP #&00
BNE .try_0x01
....
.try_0x01 LDA opcode
CMP #&01
BNE .try_0x02
....
.try_0x02
Which means if you had opcode 0xff, the emulator will waste a lot of time
finding your instruction. I have seen some compilers optimise the very
same C code to :
JMP (choice_table,opcode)
.choice_0x00 ...
.choice_0x01 ...
.choice_0x02 ...
.choice_0x03 ...
....
.choice_0xff ...
.choice_table EQUW choice_0x00
.choice_table EQUW choice_0x01
.choice_table EQUW choice_0x02
.choice_table EQUW choice_0x03
.choice_table EQUW choice_0x04
However, the assembly code it generates is not quite as short or as
simple as the above. It does a fair amount of messing about with
choice_table and opcode, before it finally decides to jump to the
right place. Overall the performance is improved (8 times!), but
there could be just that little more improvement.
I have tried to force the C compiler to do better, and have been
trying to find a better command than switch, I have tried things
like
main()
{
char *opcode_table[256]; /* 256 array of labels. */
int opcode;
opcode_table[0x00] = opcode_00; /* assigning labels to the array. */
opcode_table[0x01] = opcode_01;
opcode_table[0x02] = opcode_02;
:
opcode_table[0xff] = opcode_ff;
:
main_cpu_loop:
opcode = fetch_opcode();
goto opcode_table[opcode]; /* jump to a label depending on opcode. */
opcode_00 : .... goto main_cpu_loop;
opcode_01 : .... goto main_cpu_loop;
opcode_02 : .... goto main_cpu_loop;
opcode_03 : .... goto main_cpu_loop;
:
}
Unfortunately, I cannot find any C syntax that gets to anything
close to the above. Any suggestions???
--
Stephen Quan (quan@... ), SysAdmin, Analyst/Programmer.
Centre for Spatial Information Studies, University of Tasmania, Hobart.
GPO BOX 252C, Australia, 7001. Local Tel: (002) 202898 Fax: (002) 240282
International Callers use +6102 instead of (002).