Difference between revisions of "Design of sxgo"
From Just in Time
(Created page with 'This page describes the main design ideas behind sxgo. The implementation of this microcontroller emulator revolves around a few main ideas: * separation of instruction decoder a…') |
|||
Line 5: | Line 5: | ||
* precompilation of instructions into 'function pointers'. Actually these would also contain bound arguments (in a similar way to boost.bind). | * precompilation of instructions into 'function pointers'. Actually these would also contain bound arguments (in a similar way to boost.bind). | ||
==Instruction Implementation== | ==Instruction Implementation== | ||
− | The idea is to have one class that consists of an SX 'state' (ram, rom, special registers, program counter) and that implements the instruction set. See the snippet below: | + | The idea is to have one class that consists of an SX 'state' (ram, rom, special registers, program counter) and that implements the instruction set. See the snippet (of file ''sx_controller.hpp'')below: |
<source lang="cpp"> | <source lang="cpp"> | ||
Line 31: | Line 31: | ||
}; | }; | ||
</source> | </source> | ||
+ | |||
+ | As you can see, most instructions become very simple member functions and their implementation is quite readable. You may notice one oddity in the implementation of the instructions: instead of having member functions called ''clr_frw'' or ''clr_w'', the sx controller implementation has a set of overloads of a single member function called ''execute'' that takes some--otherwise ignored--first argument of some type with names like ''clr_frw''. The reason for this is best explained after some explanation of the implementation of the [[#Instruction set|instruction set]] and the [[#Instruction decoder|instruction decoder]]. It has all to do with the fact that the instruction set is defined independently of it's implementaton and in fact there are more than one implementations of the instructions. | ||
+ | |||
+ | ==Instruction set== | ||
+ | As could be seen in the previous Section, the implementation of the sx instruction set was all in terms of an ''execute'' method that is overloaded for several types, each type representing one instruction. Defining the instruction set becomes therefore a matter of defining a set of types, one for each instruction. | ||
+ | |||
+ | In order to facilitate instruction decoding, the instruction types will be enhanced with information about their bit-patterns. The instruction list for sxgo can be found in ''sx_instruction_list.hpp'' and has the following form: | ||
+ | <source lang="cpp"> | ||
+ | // ... | ||
+ | // define some operand (argument) types. | ||
+ | struct register_ : masked_argument< 000011111> {}; | ||
+ | struct bit_ : masked_argument< 011100000> {}; | ||
+ | |||
+ | // ... | ||
+ | // define some instruction word patterns | ||
+ | struct clr_w : word< 000001000000> {}; | ||
+ | struct add_w_fr : word< 0001110, register_> {}; | ||
+ | struct sb_fr_bit : word< 0111 , register_, bit_> {}; | ||
+ | |||
+ | // ... | ||
+ | </source> | ||
+ | |||
+ | The code above encodes the following information: | ||
+ | ;operands: The code shows two operand types (there are more). In an SX microcontroller, operands are always encoded in the same position, registers are encoded in the least significant 5 bits of the instruction word and bit-positions (0-7) are encoded in bits 5, 6 and 7 of an instruction word. | ||
+ | ;word bit patterns: As can be seen above, the '''''clr w''''' instruction takes no arguments and is recognized by the bit-pattern "000001000000" (SX instructions are always 12 bit words). The '''''add w, fr''''' instruction takes one argument (the register, or ram location where the value can be found to add to the w register). Finally, the '''''sb fr.bit'''' instruction (set a single bit in a ram location) takes an 'fr' argument (the ram location) and a bit number. Note also that, although the bit number is more to the 'left' in the instruction word, the register argument is mentioned first for this instruction word. |
Revision as of 00:31, 13 July 2009
This page describes the main design ideas behind sxgo. The implementation of this microcontroller emulator revolves around a few main ideas:
- separation of instruction decoder and instruction implementation
- a meta-programmed list of instructions
- using metaprogramming to create a fast instruction decoder
- precompilation of instructions into 'function pointers'. Actually these would also contain bound arguments (in a similar way to boost.bind).
Instruction Implementation
The idea is to have one class that consists of an SX 'state' (ram, rom, special registers, program counter) and that implements the instruction set. See the snippet (of file sx_controller.hpp)below:
<source lang="cpp"> struct sx_controller_impl {
// snip... // note that this is simplified source code, this does not set any // flags yet. void execute( const clr_fr &, int arg_register) { ram( arg_register) = 0; }
void execute( const clr_w &) { w = 0; }
void execute( const mov_w_not_fr &, int arg_register) { w = ~ram( arg_register); }
// etc...
}; </source>
As you can see, most instructions become very simple member functions and their implementation is quite readable. You may notice one oddity in the implementation of the instructions: instead of having member functions called clr_frw or clr_w, the sx controller implementation has a set of overloads of a single member function called execute that takes some--otherwise ignored--first argument of some type with names like clr_frw. The reason for this is best explained after some explanation of the implementation of the instruction set and the instruction decoder. It has all to do with the fact that the instruction set is defined independently of it's implementaton and in fact there are more than one implementations of the instructions.
Instruction set
As could be seen in the previous Section, the implementation of the sx instruction set was all in terms of an execute method that is overloaded for several types, each type representing one instruction. Defining the instruction set becomes therefore a matter of defining a set of types, one for each instruction.
In order to facilitate instruction decoding, the instruction types will be enhanced with information about their bit-patterns. The instruction list for sxgo can be found in sx_instruction_list.hpp and has the following form: <source lang="cpp"> // ... // define some operand (argument) types. struct register_ : masked_argument< 000011111> {}; struct bit_ : masked_argument< 011100000> {};
// ... // define some instruction word patterns struct clr_w : word< 000001000000> {}; struct add_w_fr : word< 0001110, register_> {}; struct sb_fr_bit : word< 0111 , register_, bit_> {};
// ... </source>
The code above encodes the following information:
- operands
- The code shows two operand types (there are more). In an SX microcontroller, operands are always encoded in the same position, registers are encoded in the least significant 5 bits of the instruction word and bit-positions (0-7) are encoded in bits 5, 6 and 7 of an instruction word.
- word bit patterns
- As can be seen above, the clr w instruction takes no arguments and is recognized by the bit-pattern "000001000000" (SX instructions are always 12 bit words). The add w, fr instruction takes one argument (the register, or ram location where the value can be found to add to the w register). Finally, the sb fr.bit' instruction (set a single bit in a ram location) takes an 'fr' argument (the ram location) and a bit number. Note also that, although the bit number is more to the 'left' in the instruction word, the register argument is mentioned first for this instruction word.