The addi (add immediate) instruction adds an immediate value
(a small signed integer within the instruction)
to the value in a register, and places the result back into the same register.
The addi instruction sets one of the internal zero
or negative condition codes depending on the value of the result.
Arithmetic and logical instructions operate on the values in
the specified source and destination registers and (with the exception
of cmp) place the result in the destination register.
For example:
add $0, $1 # r0 = r0 + r1
cmp $2, $3 # r2 - r3 (set condition codes only, discard result)
These instructions must include
add (addition),
sub (subtraction),
and
cmp (comparison).
All of these instructions set one of the internal zero or
negative condition codes depending on the value of the
result.
The lw (load word) and sw (store
word) instructions add a 2-bit immediate value to the value in one
register (ra) to calculate a memory address, then either load the
value of the memory word at that address into another register (rw) or
store the register's value at the calculated memory address. For example:
lw $1, 1($0) # r1 = memory[r0+1]
sw $2, 0($0) # memory[r0] = r2
Branch instructions behave as follows. If the condition indicated by the 2-bit condition code is true, the next instruction to be executed is located in memory at the address given by adding the immediate address offset (a 4-bit signed integer within the instruction) to the address of the next instruction. Otherwise, the next instruction in order is executed.
The condition is based on the result of the immediately previous arithmetic/logical instruction:
addi (add
immediate) instruction as large as possible, yet maintain
orthogonality as much as possible. nop (no operation) instruction that does nothing.
The machine language instruction for nop
must be all
zeros. This insruction might not preserve the values of the condition
codes, thus a nop should not be placed between an
arithmetic/logical instruction and a conditional branch. A typed write-up of your instruction set, including a diagram of the field layout for each type of instruction, a description of what the values in each field mean, and the assembly language notation for each instruction. Explain the choices you made in the design of your instruction set. If you add any instruction(s) with a different format, explain their format.
Translate one or both of the following C++ code segments into functionally equivalent assembly code for your machine. You may use any additional instructions that you invented.
sum = 0;
for (k = 0; k < n; k++)
{
sum += k;
}
sum = 0;
for (k = 0; k < n; k++)
{
sum += list[k];
}
Assume the following initial register assignments:
| Register | Value |
|---|---|
| 0 | the memory address of list[0] |
| 1 | sum |
| 2 | k |
| 3 | n |
First try to write assembly code assuming that there are no limits on the number of available registers or the size of immediate values within instructions, then modify your code to take these limitations into account. If you cannot completely satisfy these limitations in your assembly code, then clearly explain which of these limitations are violated.