On Thu, Feb 06, 2003 at 01:37:42PM +0100, Leopold Toetsch wrote: > This is one thing I allways wanted to try ;-) > > fast_core MOps: 11 > Prederef: 17.5 > CGoto MOps: 19.4 > CGP MOps: 27.5 > CGP -O3 MOps: 65 !!!1 > > This runloop combines the faster dispatch of opcodes via computed goto > and the clever register addressing due to predereferencing registers and > constants.
This generates some pretty good code (for instance, for sub_i_i_i) : (*(INTVAL *)cur_opcode[1]) = (*(INTVAL *)cur_opcode[2]) - (*(INTVAL *)cur_opcode[3]); goto *ops_addr[*(cur_opcode += 4)]; mov 0x4(%esi),%ecx mov 0x8(%esi),%edx mov 0xc(%esi),%eax mov (%eax),%eax mov (%edx),%edx sub %eax,%edx mov %edx,(%ecx) add $0x10,%esi mov (%esi),%eax shl $0x2,%eax jmp *0x80f75a0(%eax) Why not also predereference the operation address? This would save a memory read. The goto would become: goto **(cur_opcode += 4); It seems hard to improve upon this. One possibility is to have some new instructions that uses an accumulator: accu = accu - (*(INTVAL *)cur_opcode[1]); goto **(cur_opcode += 2); mov 0x4(%esi),%eax mov (%eax),%eax sub %ebx,%eax add $0x8,%esi jmp *(%esi) -- Jérôme