Typically, when programming an emulator one of the most tricky parts to get down is the efficient decoding of operations.
This can sometimes represent one of the biggest overheads of an emulator and it’s important to be able to write an efficient and easily maintable decoder.

While I was writing my Chip 8 emulator, I came across many different ways of decoding, and through trying a lot of them I got a good feel of the advantages and disadvantages of some of the more common methods.

Switch statements Link to heading

One common approach, found especially often in emulators for small systems like Chip-8, and emulators wrote by those new to emulator development is a massive switch statement.
The way it works is pretty simple: switch on some bit or byte of an instruction, and run the instruction corresponding to it.

Info
With most systems, you may need to nest switch statements or use extra if statements to get rid of ambuiguous cases where multiple instructions have some bytes or bits in common
This is the approach that immediately springs to mind when you first start to think of how to approach operation decoding, and for the purposes of emulating simple machines like Chip-8, it works just fine.
Most compilers should turn such a switch statement into a jump table so long as enough cases are covered.

Optimisations like these make switch statements performant enough for simple emulation, and I initially set out to use one, but came across one major downside: clarity.
A massive switch statement becomes a pain to sort through, and it’s often quite unwieldy and inelegant to fix any bugs with it.
Performance was also a factor, while as I mentioned, a jump table would be perfectly fast and efficient enough for my needs, some basic investigation reveals that it’s possible to get better performance, and better clarity, using a method such as :

Function Pointers Link to heading

This involves creating an array of pointers to functions that implement the instructions of the emulator.
The main point of consideration is what you are going to use as the index into the array, analogous to choosing which bits to switch on in the prior method.

Info
Similarly to the switch statement, you may have to use nested arrays of function pointers in cases where multiple instructions have some bits in common.

This is both more performant, and more elegant that a giant switch statement, and is the method I personally chose for my Chip 8 emulator.

Overall takeaway Link to heading

One interesting overall takeaway is that the specific performance of both these methods are very dependent on other, external factors like the toolchain / compiler used.
When considering performance, specific testing and profiling should be done This means that a higher priority should be given to ease of expansion, and clarity, as these are metrics that are immediately obvious and won’t change very much from toolchain to toolchain.