Op-code dispatcher 
Author Message
 Op-code dispatcher

A loong time ago when the 8086 was new, and there was a lot more software
available for CP/M and the 8080 processor, I wrote a 8080 simulator and
CP/M emulator, so we could run all that fine :) CP/M software.

The biggest bottleneck was dispatching the op-codes to the 256 op-code
handlers.
Each 8080 opcode could be handled by surprisingly few 8086 instructions.
But the opcode dispatcher was always a major time waster.

Is there a *really* fast way to do this?

Here's some of the schemes I tried, from the obvious to the ridiculous.
Remember this was for the 8086 on which LODSB was pretty fast.
Apologies if my failing memory has recalled some impossible code.

I tried:
(1)  Using a jump table:

     LODSB   ; get op code
     mov   bl,al
     add    bx,bx
     jmp    OpTab[bx]

(2)  Waste some memory and jump to 32 byte sections:

    LODSB   ; get op code
    mov   bx,ax
    add    bx,bx
    add    bx,bx
    add    bx,bx
    add    bx,bx
    add    bx,bx             ;  note: this is before  sal  bx,5  was
tolerably fast
    jmp    [bx+opbase]

(3)  Waste lots of memory and jump to 256 byte sections:
     LODSB
     mov   bh,al
     jmp   [bx+opbase]

(4)  If every op code can be handled in 16 bytes, go directly to seg reg:

    preload ah with base segment, dx with zero
    LODSB
    mov   bx,ax
    jmp   bx:dx

(5)  Desperate, mess with CS:
   preload ah with high part of desired CS
   LODSB
   push  ax
   pop   cs       ( I know, this op code is used for something else )

---------

Which brings up a good question-- since most processors nowdays often
spend some time emulating some other processor, why dont they have an
instruction for this?
Something like  LODSB; jmp [si+al*64]  would be a nifty instruction and
wouldnt take much silicon or microcode.



Mon, 17 Jul 2000 03:00:00 GMT  
 Op-code dispatcher

Quote:

> A loong time ago when the 8086 was new, and there was a lot more software
> available for CP/M and the 8080 processor, I wrote a 8080 simulator and
> CP/M emulator, so we could run all that fine :) CP/M software.

> The biggest bottleneck was dispatching the op-codes to the 256 op-code
> handlers.
> Each 8080 opcode could be handled by surprisingly few 8086 instructions.
> But the opcode dispatcher was always a major time waster.

> Is there a *really* fast way to do this?

> Here's some of the schemes I tried, from the obvious to the ridiculous.
> Remember this was for the 8086 on which LODSB was pretty fast.
> Apologies if my failing memory has recalled some impossible code.

> I tried:
> (1)  Using a jump table:

>      LODSB   ; get op code
>      mov   bl,al
>      add    bx,bx
>      jmp    OpTab[bx]

> (2)  Waste some memory and jump to 32 byte sections:

>     LODSB   ; get op code
>     mov   bx,ax
>     add    bx,bx
>     add    bx,bx
>     add    bx,bx
>     add    bx,bx
>     add    bx,bx             ;  note: this is before  sal  bx,5  was
> tolerably fast
>     jmp    [bx+opbase]

on current x86 processors given that you have to do a jump which flushes
thepipeline, a reasonable alternative is to make a table of jump instructions
(three bytes
+ 1 byte padding) and do a jump to a jump.  That is a little slower than
wasting lots
of space but keeps you from wasting lots of space.  This would also allow you

to use the 386+ scaled address modes to do the shift.

- Show quoted text -

Quote:
> (3)  Waste lots of memory and jump to 256 byte sections:
>      LODSB
>      mov   bh,al
>      jmp   [bx+opbase]

> (4)  If every op code can be handled in 16 bytes, go directly to seg reg:

>     preload ah with base segment, dx with zero
>     LODSB
>     mov   bx,ax
>     jmp   bx:dx

> (5)  Desperate, mess with CS:
>    preload ah with high part of desired CS
>    LODSB
>    push  ax
>    pop   cs       ( I know, this op code is used for something else )
> ---------

> Which brings up a good question-- since most processors nowdays often
> spend some time emulating some other processor, why dont they have an
> instruction for this?
> Something like  LODSB; jmp [si+al*64]  would be a nifty instruction and
> wouldnt take much silicon or microcode.

YEah.  But consider using 386 addressing modes.  You take a hit from the
ADRSIZE
prefix but don't have to do a register transfer... how about:

sub    ax,ax
lodsb
shl    ax,5
jmp    [eax]

That of course assumes your table is based at address zero in the segment,
but if
you are doing real-mode programming this is not a problem.

Another possible approach is to use lodsw to advantage:

lodsw
dec si
sub al,al
jmp [eax]

Unfortunately this will cause a GPF on modern x86 processors, when fetching
from
address 0 in the segment.

Can you do a move to CS?  If so then:

sub    ax,ax
lodsb
add    ax,baseseg
mov    cs,ax

will get you to the new segment, but you have to think about how you are
going
to line things up.  A slight variation on this technique would be to use a
RETF
to change the segment register but that pushes stuff on the stack and would
probably be slow in the absence of caching.

You also have to consider how you are going to get back to the interpreter,
and you have
to consider how to stop the program.  I would probably put the interpreter
address in
a register, say di, and then do a jmp[di] to get back to the interpreter.  If
you want
to stop the program (say you press the break key) the break routine just
replaces the value in di with a routine that exits the interpreter and then
lets the
current instructrion finish..

Another key problem is where to keep the simulated register data.  If
simulating say
a 6502 you can cache them in the registers... but if simulating say a Z80 you
cannot
do that entirely given that you need to use at least AX and SI for the
interpreter.

I would cache the most-used registers and then have BP point to the rest in
the
stack-seg.

David



Tue, 18 Jul 2000 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Interpretation of binary-op followed by unary-op

2. Op Code Matrix Enigma

3. getting undefined op-code with macros

4. Forth-83 coded do-loop built on for-next opcode

5. M68000 op code

6. RDMSR/WRMSR op code question.

7. Looking for a list of machine op codes

8. Good book for x86 based OP codes?

9. Looking for op code list

10. Undocumented op-codes of MC68000????

11. x86 ASM tute/coding docs/opcode list/interupt list

12. op code/memory question

 

 
Powered by phpBB® Forum Software