Computer Architecture Lab/SS2013/GROUP1 LAB2

The instruction set used is a simplifyed subset of the MIPS32 instruction set abbreviated sMIPS which excludes floating point types, unsigned types, interaction with coprocessors as well as the syscall,break and jump and link instructions. Further many of the "immediate" instructions has been made into pseudo-instructions typically requireing more instruction cycles to execute.

The remaining ISA is greatly inspired by the MIPS32 ISA and likewise makes use of 32 registers $0 - $31 where $0 is defined as having the constant value 0. the LO and HI registers are here implemented as regular GP-registers $26 - $27 respectively that would otherwise be used for OS kernel in MIPS32. All in all this ISA is compatible with the MIPS32 ISA and vice versa (if resolving the psedou-instructions).

Integers' MSB are regarded as a sign-extension, but the signs are otherwise not pertained in e.g. shifts, so it is the programmers responsibility to ensure the signs are pertained by e.g. flipping the MSB after a left-shift back to it's previous value.

sMIPS instruction formats

edit

Instructions are divided into three types: R, I and J. Every instruction starts with a 6-bit opcode. In addition to the opcode, R-type instructions specify three registers, a shift amount field, and a function field; I-type instructions specify two registers and a 16-bit immediate value; J-type instructions follow the opcode with a 26-bit jump target.

The following are the three formats used for the core instruction set:

Type -31-                                 format (bits)                                 -0-
R opcode (6) rs (5) rt (5) rd (5) shamt (5) funct (6)
I opcode (6) rs (5) rt (5) immediate (16)
J opcode (6) address (26)

The J-type has been preserved to allow for specifying addresses using 26 bit. Otherwise ANDI could have been used, but would only give us a 16bit address space.

With the following instruction-set where $26 = LO and $27 = HI :

sMIPS instruction set

edit
Category Name Instruction syntax Meaning Format/opcode/funct Notes/Encoding
Arithmetic Add add $d,$s,$t $d = $s + $t R 0 2116 adds two registers
000000ss sssttttt ddddd--- --100001
Subtract sub $d,$s,$t $d = $s - $t R 0 2316 subtracts two registers
000000ss sssttttt ddddd000 00100011
Add immediate addi $t,$s,C $t = $s + C I 916 - Used to add constants (and also to copy one register to another: addi $1, $2, 0)
001001ss sssttttt CCCCCCCC CCCCCCCC
Multiply mult $s,$t LO = (($s * $t) << 32) >> 32;
HI = ($s * $t) >> 32;
R 0 1916 Multiplies two registers and puts the 64-bit result in two special memory spots - LO and HI. Alternatively, one could say the result of this operation is: (int HI,int LO) = (64-bit) $s * $t . See mfhi and mflo for accessing LO and HI regs.
Divide div $s, $t LO = $s / $t     HI = $s % $t R 0 1B16 Divides two registers and puts the 32-bit integer result in LO and the remainder in HI.
Data Transfer Load word lw $t,C($s) $t = Memory[$s + C] I 2316 - loads the word stored from: MEM[$s+C] and the following 3 bytes.
Store word sw $t,C($s) Memory[$s + C] = $t I 2B16 - stores a word into: MEM[$s+C] and the following 3 bytes. The order of the operands is a large source of confusion.
Logical And and $d,$s,$t $d = $s & $t R 0 2416 Bitwise and
000000ss sssttttt ddddd--- --100100
Or or $d,$s,$t $d = $s | $t R 0 2516 Bitwise or
Exclusive or xor $d,$s,$t $d = $s ^ $t R 0 2616
Nor nor $d,$s,$t $d = ~ ($s | $t) R 0 2716 Bitwise nor
Set on less than slt $d,$s,$t $d = ($s < $t) R 0 2A16 Tests if one register is less than another.
Bitwise Shift Shift left logical sll $d,$t,shamt $d = $t << shamt R 0 0 shifts shamt number of bits to the left (multiplies by  )
Shift right logical srl $d,$t,shamt $d = $t >> shamt R 0 216 shifts shamt number of bits to the right - zeros are shifted in (divides by  ). Note that this instruction only works as division of a two's complement number if the value is positive.
Conditional branch Branch on equal beq $s,$t,C if ($s == $t) go to PC+4+4*C I 416 - Goes to the instruction at the specified address if two registers are equal.
000100ss sssttttt CCCCCCCC CCCCCCCC
Branch on not equal bne $s,$t,C if ($s != $t) go to PC+4+4*C I 516 - Goes to the instruction at the specified address if two registers are not equal.
Unconditional jump Jump j C PC = PC+4[31:28] . C*4 J 216 - Unconditionally jumps to the instruction at the specified address.
Jump register jr $s goto address $s R 0 816 Jumps to the address contained in the specified register

Pseudo instructions

edit

These instructions are accepted by the MIPS assembler, although they are not real instructions within the MIPS instruction set. Instead, the assembler translates them into sequences of real instructions.

Name instruction syntax Real instruction translation meaning
And immediate andi $t,$s,C addi $1,$0,C; and $t,$1,$s $t = $s & C
or immediate ori $t,$s,C addi $1,$0,C; or $t,$1,$s C
Set on less than immediate slti $t,$s,C addi $1,$0,C; slt $t,$1,$s $t = ($s < C)
Move move $t,$s addi $t,$s,0 R[t]=R[s]
Move from low mflo $d move $d,$26 R[t]="LO"
Move from high mflh $d move $d,$27 R[t]="HI"
Clear clear $rt add $rt,$zero,$zero R[rt]=0
Not not $rt, $rs nor $rt, $rs, $zero R[rt]=~R[rs]
Load Address la $rd, LabelAddr lui $rd, LabelAddr[31:16]; ori $rd,$rd, LabelAddr[15:0] $rd = Label Address
Load Immediate li $rd, IMMED[31:0] lui $rd, IMMED[31:16]; ori $rd,$rd, IMMED[15:0] $rd = 32 bit Immediate value
Branch unconditionally b Label beq $zero,$zero,Label PC=Label
Branch and link bal Label bgezal $zero,Label R[31]=PC+8; PC=Label
Branch if greater than bgt $rs,$rt,Label slt $at,$rt,$rs; bne $at,$zero,Label if(R[rs]>R[rt]) PC=Label
Branch if less than blt $rs,$rt,Label slt $at,$rs,$rt; bne $at,$zero,Label if(R[rs]<R[rt]) PC=Label
Branch if greater than or equal bge $rs,$rt,Label slt $at,$rs,$rt; beq $at,$zero,Label if(R[rs]>=R[rt]) PC=Label
Branch if less than or equal ble $rs,$rt,Label slt $at,$rt,$rs; beq $at,$zero,Label if(R[rs]<=R[rt]) PC=Label
Branch if greater than unsigned bgtu $rs,$rt,Label if(R[rs]>R[rt]) PC=Label
Branch if greater than zero bgtz $rs,Label if(R[rs]>0) PC=Label
Branch if equal to zero beqz $rs,Label if(R[rs]==0) PC=Label
Multiplies and returns only first 32 bits mul $d, $s, $t mult $s, $t; mflo $d $d = $s * $t
Divides and returns quotient div $d, $s, $t div $s, $t; mflo $d $d = $s / $t
Divides and returns remainder rem $d, $s, $t div $s, $t; mfhi $d $d = $s % $t
No operation nop sll $0,$0,0 (0x00000000) NOP

sMIPS Assembler

edit

A very simple single-file assembler supporting the described instructions has been developed and can be downloaded HERE.

The assembler is a simple two pass assembler, first resolving all labels into addresses and pseduo-instuctions into real instructions then translating the instructions into machine code. There are some limitations regarding labels, namely that they should be prefixed "lab_" and that they have to be declared on a separate line.

The assembler is made in Java and can be run with the following commands :

Java -jar sMIPSAssembler.jar <infile> <outfile> [mode = "B"]

Where type can have the values B (binary), H (hex), S (sMIPS instructions) or I (integer) depending on the outfile representation. If S is selected the output is the conversion from MIPS32 to sMIPS. Default mode is B.

Not much effort has been put into reporting detailed error messages, so the programmer should carefully (syntactically) type the correct instructions.