< Computer Architecture Lab < SS2013

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

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-
Ropcode (6)rs (5)rt (5)rd (5)shamt (5)funct (6)
Iopcode (6)rs (5)rt (5)immediate (16)
Jopcode (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

CategoryNameInstruction syntaxMeaningFormat/opcode/functNotes/Encoding
Arithmetic Addadd $d,$s,$t$d = $s + $tR02116adds two registers
000000ss sssttttt ddddd--- --100001
Subtractsub $d,$s,$t$d = $s - $tR02316subtracts two registers
000000ss sssttttt ddddd000 00100011
Add immediateaddi $t,$s,C$t = $s + CI916-Used to add constants (and also to copy one register to another: addi $1, $2, 0)
001001ss sssttttt CCCCCCCC CCCCCCCC
Multiplymult $s,$tLO = (($s * $t) << 32) >> 32;
HI = ($s * $t) >> 32;
R01916Multiplies 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.
Dividediv $s, $tLO = $s / $t     HI = $s % $tR01B16Divides two registers and puts the 32-bit integer result in LO and the remainder in HI.
Data Transfer Load wordlw $t,C($s)$t = Memory[$s + C]I2316-loads the word stored from: MEM[$s+C] and the following 3 bytes.
Store wordsw $t,C($s)Memory[$s + C] = $tI2B16-stores a word into: MEM[$s+C] and the following 3 bytes. The order of the operands is a large source of confusion.
Logical Andand $d,$s,$t$d = $s & $tR02416Bitwise and
000000ss sssttttt ddddd--- --100100
Oror $d,$s,$t$d = $s | $tR02516Bitwise or
Exclusive orxor $d,$s,$t$d = $s ^ $tR02616
Nornor $d,$s,$t$d = ~ ($s | $t)R02716Bitwise nor
Set on less thanslt $d,$s,$t$d = ($s < $t)R02A16Tests if one register is less than another.
Bitwise Shift Shift left logicalsll $d,$t,shamt$d = $t << shamtR00shifts shamt number of bits to the left (multiplies by )
Shift right logicalsrl $d,$t,shamt$d = $t >> shamtR0216shifts 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 equalbeq $s,$t,Cif ($s == $t) go to PC+4+4*CI416-Goes to the instruction at the specified address if two registers are equal.
000100ss sssttttt CCCCCCCC CCCCCCCC
Branch on not equalbne $s,$t,Cif ($s != $t) go to PC+4+4*CI516-Goes to the instruction at the specified address if two registers are not equal.
Unconditional jump Jumpj CPC = PC+4[31:28] . C*4J216-Unconditionally jumps to the instruction at the specified address.
Jump registerjr $sgoto address $sR0816Jumps to the address contained in the specified register

Pseudo instructions

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.

Nameinstruction syntaxReal instruction translationmeaning
And immediateandi $t,$s,Caddi $1,$0,C; and $t,$1,$s$t = $s & C
or immediateori $t,$s,Caddi $1,$0,C; or $t,$1,$sC
Set on less than immediateslti $t,$s,Caddi $1,$0,C; slt $t,$1,$s$t = ($s < C)
Movemove $t,$saddi $t,$s,0R[t]=R[s]
Move from lowmflo $dmove $d,$26R[t]="LO"
Move from highmflh $dmove $d,$27R[t]="HI"
Clearclear $rtadd $rt,$zero,$zeroR[rt]=0
Notnot $rt, $rsnor $rt, $rs, $zeroR[rt]=~R[rs]
Load Addressla $rd, LabelAddrlui $rd, LabelAddr[31:16]; ori $rd,$rd, LabelAddr[15:0]$rd = Label Address
Load Immediateli $rd, IMMED[31:0]lui $rd, IMMED[31:16]; ori $rd,$rd, IMMED[15:0]$rd = 32 bit Immediate value
Branch unconditionallyb Labelbeq $zero,$zero,LabelPC=Label
Branch and linkbal Labelbgezal $zero,LabelR[31]=PC+8; PC=Label
Branch if greater thanbgt $rs,$rt,Labelslt $at,$rt,$rs; bne $at,$zero,Labelif(R[rs]>R[rt]) PC=Label
Branch if less thanblt $rs,$rt,Labelslt $at,$rs,$rt; bne $at,$zero,Labelif(R[rs]<R[rt]) PC=Label
Branch if greater than or equalbge $rs,$rt,Labelslt $at,$rs,$rt; beq $at,$zero,Labelif(R[rs]>=R[rt]) PC=Label
Branch if less than or equalble $rs,$rt,Labelslt $at,$rt,$rs; beq $at,$zero,Labelif(R[rs]<=R[rt]) PC=Label
Branch if greater than unsignedbgtu $rs,$rt,Labelif(R[rs]>R[rt]) PC=Label
Branch if greater than zerobgtz $rs,Labelif(R[rs]>0) PC=Label
Branch if equal to zerobeqz $rs,Labelif(R[rs]==0) PC=Label
Multiplies and returns only first 32 bitsmul $d, $s, $tmult $s, $t; mflo $d$d = $s * $t
Divides and returns quotientdiv $d, $s, $tdiv $s, $t; mflo $d$d = $s / $t
Divides and returns remainderrem $d, $s, $tdiv $s, $t; mfhi $d$d = $s % $t
No operationnopsll $0,$0,0 (0x00000000)NOP

sMIPS Assembler

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 seperate 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.

This article is issued from Wikiversity. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.