Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to using function-pointers. #2

Closed
skx opened this issue Oct 6, 2014 · 1 comment
Closed

Move to using function-pointers. #2

skx opened this issue Oct 6, 2014 · 1 comment

Comments

@skx
Copy link
Owner

skx commented Oct 6, 2014

Rather than having a giant switch statement, with a case for each opcode, we should break out the implementations of the opcodes into their own functions.

If we define an array of 255-opcodes in the svm_t function then we can use function pointers to invoke the correct function.

  • Pros
    • The code becomes more readable.
    • We could have a default handler which dumps "unknown instruction" for debugging purposes.
    • This would allow host-applications to define host-specific opcodes.
  • Cons
    • Significant churn.
    • Wastes 255 * (function-pointer size) bytes per svm_t instance.
    • We have some repetition setting up the opcode handlers - both defining the function and then allocating it.
@skx
Copy link
Owner Author

skx commented Oct 6, 2014

I have a workable proof of concept at the moment, but there are implications I'd not forseen.

  • The "running" flag isn't accessible to the op_exit primitive, so it must be moved to part of the CPU-state.
  • The use of the restart label (+ associated goto) to allow updating IP via jump instructions won't work.

For the moment I've updated my operations signature to this:

Bool op_foo( void * input );

If that function returns TRUE then it is assumed IP has been updated and it is left alone, otherwise it increments appropriately. This works but it feels a little unclean.

Will commit shortly. Just tweaking the emacs macro to mass-edit ;)

skx added a commit that referenced this issue Oct 6, 2014
This is a hugely-churnful update which moves all the opcode-processing
out of the large switch/case statement and into a distinct routine for
each opcode.

This will cause a slowdown, but not significantly enough to care about.

Updates #2 - which I will leave open until I've moved the code into
external files.
This was referenced Oct 6, 2014
@skx skx closed this as completed in d6d3a4b Oct 6, 2014
skx added a commit that referenced this issue Oct 7, 2014
Since the jump-handling changed as a result of #2 we have to
return `true` from handlers that tweak the IP value.

This updates and closes #5 - tested this time!

**NOTE**: You will need to recompile programs, because the string
registers now need two bytes.
skx added a commit that referenced this issue Oct 13, 2014
We needed to update the storing of integers, because the
following program failed:

        #
        # Set the byte at 0x5000 to read "NOP"
        #
        store #1, 0x50
        store #2, 0x5000
        poke #1, #2

        #
        # Set the byte at 0x5001 to read "EXIT"
        #
        store #1, 0
        store #2, 0x5001
        poke #1, #2

        #
        # Jump to that new code.
        #
        goto 0x5000

Now it works as expected.
skx added a commit that referenced this issue Oct 13, 2014
The following code now compiles and executes:

        goto run
    :code
        store #1, "Steve Kemp\n"
        print_str #1
        exit
    :run
        store #1, 0x5000
        store #2, code
        # len is guess here
        store #3, 50
        memcpy #1, #2, #3

        goto 0x5000

This closes #10.
skx added a commit that referenced this issue Oct 19, 2014
So now we can do "set reg1 = reg2", via "store #1, #2" and it works
as the following program demonstrates:

        # reg1 = steve...
        store #1, "steve\n"
        print_str #1

        # now reg2 == reg1
        store #2, #1
        print_str #2

        # and so a comparison is OK
        cmp #1, #2
        jmpz OK

        store #1, "ERROR reg1 != reg2"
        print_str #1
        exit

     :OK
        store #1, "'store #1, #2' worked!\n"
        print_str #1
        exit

This means we now have:

    store #1, "String"   # string
    store #1, 0x3342     # number
    store #1, label      # label
    store #1, #2         # register
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant