# Introduction # This page introduces the first version of specification for _Simmy_, an educational simulator for _SIM_ computer architecture. _SIM_ stands for _Simple Integer Machine_. It is not an existing architecture, but it implements all significant features of real computer architectures. Its description will be presented step by step. Each new version will add new commands and requirements and also change previous ones. This version provides only an initial information about _SIM_. A very limited, but still operable, set of instructions is introduced and also some helpful tips and requirement to develop the functional simulator (the first version of _Simmy_) are presented in the following sections. . # Hardware specification # --- ## Registers ## --- _SIM_ architecture supports `16` general purpose integer registers. Each registers contains `16` bits for storing an unsigned value and `1` bit for a sign. If the sign bit is equal to `0` the register store a negative value, otherwise, a positive ones. The following figure represents the logical structure of the register file: ``` register number sign unsigned value ┌―――┐ ┌――――――――――――――――――――――┐ r0 │ 0 │ │ 0101 0001 0000 1010 │ ← decimal -20746 r1 │ 1 │ │ 0000 0000 0001 0011 │ ← decimal 19 r2 │ 0 │ │ 0111 1101 0110 0110 │ ← decimal -32102 ... ... ... ... ... ... r15 │ 1 │ │ 0110 01101 0000 1111 │ ← decimal 52495 └―――┘ └――――――――――――――――――――――┘ ``` . # Instruction set # --- This sections provides detailed description for all _SIM_ instructions. In this version each instruction has the same fixed length of _5 Bytes_. The first byte is always an operation code (so-called _opcode_). The content of the other bytes depends on the instruction type. The supported types are presented below. |Note: The terms _instruction_, _operation_ and _command_ are often used as synonyms. | |:-----------------------------------------------------------------------------------------------------------------------| . ## Operations with two operands ## --- This type generally includes main arithmetical and logical instructions. The result of an operation is _always_ saved into the first operand (`op1`), consequently, `op1` _must_ be a register number. The second operand (`op2`) can be either a value or a register number. ### Instruction structure ### As it was previously said, each instruction consists of _5 Bytes_. These bytes are described in the following list. Note that numbers of bytes in the instruction is agreed with numbers of items in the list.
0.0.op2. This bit defines if op2 is a register or value (0 -- register, 1 -- value).op2. Note it is used only if op2 is a value, otherwise, it must be equal to 0. This bit defines if op2 value is positive or negative (0 -- negative, 1 -- positive).0.0.0.0.op1. It is always a register number. op2.op2.AND ###
A bitwise `AND` takes two binary representations of equal length and performs the logical `AND` operation on each pair of corresponding bits. For each pair, the result is `1` if the first bit is `1` _and_ the second bit is `1`; otherwise, the result is `0`. For example:
```
# r3 stores `1 0000 0000 0000 0111`, i.e. (decimal 7)
# r5 stores `0 1110 0000 0000 0110`, i.e. (decimal -57350)
AND r3, r5;
# r3 is changed to `0 0000 0000 0000 0110`, i.e. (decimal 5).
```
Note that `AND` also changes the sign bit.
### OR ###
A bitwise `OR` takes two bit patterns of equal length and performs the logical inclusive `OR` operation on each pair of corresponding bits. For each pair, the result is `1` if the first bit is `1` _or_ the second bit is `1` _or_ both bits are `1`; otherwise, the result is `0`. For example:
```
# r3 stores `1 0000 0000 0000 0111`, i.e. (decimal 7)
# r5 stores `0 1110 0000 0000 0110`, i.e. (decimal -57350)
OR r3, r5;
# r3 is changed to `1 1110 0000 0000 0111`, i.e. (decimal 57351).
```
Note that `OR` also changes the sign bit.
### XOR ###
A bitwise _exclusive_ `OR` takes two bit patterns of equal length and performs the logical `XOR` operation on each pair of corresponding bits. The result in each position is `1` if only the first bit is `1` _or_ only the second bit is `1`, but will be `0` if both are `1` or both are `0`. This is equivalent to being `1` if the two bits are different, and `0` if they are the same. For example:
```
# r3 stores `1 0000 0000 0000 0111`, i.e. (decimal 7)
# r5 stores `0 1110 0000 0000 0110`, i.e. (decimal -57350)
XOR r3, r5;
# r3 is changed to `1 1110 0000 0000 0001`, i.e. (decimal 57345).
```
Note that `XOR` also changes the sign bit.
### Integer arithmetics ###
| **Opcode** | **Notation** | **Short Description** |
|:------------|:-------------|:----------------------|
| `1000 0010` | `ADD` | Integer addition |
| `1000 0011` | `SUB` | Integer subtraction |
| `1000 0001` | `MUL` | Integer multiplication |
| `1000 0000` | `DIV` | Integer devision |
| `1000 0100` | `MOV` | Move a value into a register |
### ADD ###
The command `ADD` performs simple decimal integer addition of two values of equal length. For example:
```
# r3 stores `1 0000 0000 1000 0111`, i.e. (decimal 135)
# r5 stores `0 0000 0000 0000 0110`, i.e. (decimal -6)
ADD r3, r5;
# r3 is changed to `1 0000 0000 1000 0001`, i.e. (decimal 129 = 135 + (-6)).
```
### SUB ###
The command `SUB` performs simple decimal integer subtraction of two values of equal length. The value from `op2` is subtracted from the value from `op1`. For example:
```
# r3 stores `1 0000 0000 1000 0111`, i.e. (decimal 135)
# r5 stores `0 0000 0000 0000 0110`, i.e. (decimal -6)
SUB r3, r5;
# r3 is changed to `1 0000 0000 1000 1101`, i.e. (decimal 141 = 135 - (-6)).
```
### MUL ###
The command `MUL` performs simple decimal integer multiplication of two values of equal length. For example:
```
# r3 stores `1 0000 0000 1000 0111`, i.e. (decimal 135)
# r5 stores `0 0000 0000 0000 0110`, i.e. (decimal -6)
MUL r3, r5;
# r3 is changed to `0 0000 0011 0010 1010`, i.e. (decimal -810 = 135 * (-6)).
```
### DIV ###
The command `DIV` performs simple decimal integer division of two values of equal length. The value from `op1` is divided by the value from `op2`. The result is rounded down. For example:
```
# r3 stores `1 0000 0000 1000 1000`, i.e. (decimal 136)
# r5 stores `0 0000 0000 0000 0110`, i.e. (decimal -6)
SUB r3, r5;
# r3 is changed to `0 0000 0000 0001 0110`, i.e. (decimal -22 = 136 / (-6)).
```
### MOV ###
The command `MOV` copies the value from `op2` into the register of `op1`. For example:
```
# r3 stores `1 0000 0000 1000 0111`, i.e. (decimal 135)
# r5 stores `0 0000 0000 0000 0110`, i.e. (decimal -6)
MOV r3, r5;
# r3 is changed to `0 0000 0000 0000 0110`, i.e. (decimal -6, a copy of r5).
```
### Floating point arithmetics ###
|Note: floating point calculations are not supported in this version. You can work only with integer numbers. |
|:---------------------------------------------------------------------------------------------------------------------------------------------|
.
## Operations with single operand ##
---
This type generally includes auxiliary arithmetical, logical and system instructions. The operand (`op`) must be a register number and the result is always saved into it.
### Instruction structure ###
As it was previously said, each instruction consists of _5 Bytes_. These bytes are described in the following list. Note that numbers of bytes in the instruction is agreed with numbers of items in the list.
0.0.0.0.0.0.0.op. It is always a register number. 0.0.NOT ###
The bitwise `NOT`, or _complement_, is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Digits which were `0` become `1`, and vice versa. For example:
```
# r3 stores `1 0000 0000 0000 0111` (decimal 7)
NOT r3;
# r3 is changed to `0 1111 1111 1111 1000` (decimal 177770).
```
Note that `NOT` also changes the sign bit.
### Integer arithmetics ###
| **Opcode** | **Notation** | **Short Description** |
|:------------|:-------------|:----------------------|
| `1100 0000` | `DEC` | Integer decrement |
| `1100 0001` | `INC` | Integer increment |
| `1100 0010` | `SSGN` | Set a new sign |
| `1100 0011` | `ISGN` | Sign inversion |
### DEC ###
The command `DEC` decreases the value from `op` by one.
```
# r3 stores `1 0000 0000 0000 0111` (decimal 7)
DEC r3;
# r3 is changed to `1 0000 0000 0000 0110` (decimal 6).
```
### INC ###
The command `INC` increases the value from `op` by one.
```
# r3 stores `1 0000 0000 0000 0111` (decimal 7)
INC r3;
# r3 is changed to `1 0000 0000 0000 1000` (decimal 8).
```
### SSGN ###
The command `SSGN` takes the sign bit and set its value into sign bit of the register of `op`, i.e. changes its sign.
```
# r3 stores `0 0000 0000 0000 0111` (decimal -7)
SSGN 1, r3;
# r3 is changed to `1 0000 0000 0000 0111` (decimal 7).
```
### ISGN ###
The command `ISGN` invert the sign of the register of `op`, i.e. change positive to negative and vice versa.
```
# r3 stores `1 0000 0000 0000 0111` (decimal 7)
ISGN r3;
# r3 is changed to `0 0000 0000 0000 0111` (decimal -7).
```
.
## Operations without operands ##
---
|Note: There is no such operation in this version.|
|:--------------------------------------------------------------------------------|
.
# Simulation #
---
In this version _Simmy_ implements only functional simulation. It means that the simulator does not count neither clocks nor any other performance data. The main purpose of this mode is to check the functional correctness of the program. The only way to do that is to execute it.
## External interfaces ##
You should create a C++ class called _Simmy_ which implements a functional simulator. It should have only two public methods: its constructor and the _Execute_ method.
The constructor receives a pointer to a byte array where instructions of a program is located. The _Execute_ method executes a certain number of instructions (as many as defined by its parameter) beginning from the first instruction in the byte array. Note that the first byte of the first instruction (i.e. its opcode) is located in the first element of the array (`bytes[0]`). When the given number of instructions is executed the method returns a value of `r0`.
```
class Simmy {
public:
Simmy ( unsigned char* bytes, unsigned int lenght);
// execute certain number of instructions
int Execute ( unsigned int number_of_instrs);
};
```
You are free to add as many additional private method and classes as you want, but you cannot change these methods.
## Getting instructions from memory ##
This section provides helpful example how you can organize reading and parsing of instructions from a byte array.
```
#include