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

Reply via email to