# MIPS (CPU)

MIPS (afkorting voor Microprocessor without Interlocked Pipeline Stages) is een processor ontworpen door John L. Hennessy. MIPS baseert zich op de RISC-processorarchitectuur.

## Geschiedenis

In 1984 verliet Hennessy de universiteit van Stanford om MIPS Computer Systems op te richten, waar hij zijn eerste MIPS-processor ontwierp en openbaar maakte, de R2000. In 1988 kwam de verbeterde versie van dit model, de R3000. Beide zijn 32-bitsprocessoren. Later kwam er ook een 64-bitsversie vrij, de R4000. Doordat SGI (Silicon Graphics), een belangrijke klant, steeds betere processoren wilde, moest er kostbaar onderzoek gedaan worden. De onderzoekskosten deden MIPS Computer Systems de das om en het bedrijf kwam in financiële moeilijkheden. SGI heeft het bedrijf toen overgenomen, zodat het onderzoek niet verloren zou gaan. Het bedrijf kreeg de naam MIPS Technologies en bestaat vandaag de dag nog steeds onder die naam.
De MIPS is een van de eerste RISC-architecturen en was een van de drie platforms waarvoor de eerste versie van Windows NT (3.5) beschikbaar kwam. Deze versie is echter niet populair geworden en verdere ondersteuning is gestopt in Windows NT 4.0.

## Gebruik

De MIPS-processoren worden vaak gebruikt in ingebedde systemen. Maar ook in enkele spelcomputers vindt men MIPS-processoren terug.
* Dvd-spelers
* Netwerken
* Draagbare Audio
* Televisieapparaten
* Printers
* Spelconsoles
** Sony
*** PlayStation PSX
*** PlayStation 2 Computer Entertainment System
*** PlayStation Portable
** Nintendo
*** Nintendo 64

## MIPS is een RISC-computer

De reduced instruction set computer (RISC) is een processorarchitectuur waarbij iedere mogelijke instructie dezelfde hoeveelheid tijd nodig heeft om uitgevoerd te worden. Daaruit is de MIPS-architectuur gegroeid.

### MIPS-geheugen

De bedoeling van het geheugen is om groepen bits op te slaan en die door te zenden wanneer ze worden opgevraagd. De meeste huidige computers slaan informatie op in meervouden van 8 bits (of 1 byte). Elke byte krijgt ook een numeriek adres toegewezen. De MIPS-processor heeft een adresgrootte van 32 bits, dus met bereik 0x00000000 tot 0xFFFFFFFF. In het geheugen kunnen zowel programma-instructies als data opgeslagen worden. Dus een van de functies van een besturingssysteem is dat het stukken geheugen kan toewijzen aan instructies of data van elk proces. Het geheugen kan zowel als little-endian als big-endian gebruikt worden. Little-endian is wanneer je het minst significante bit eerst in het geheugen plaatst. Big-endian houdt de omgekeerde volgorde in.

### MIPS-instructieset

MIPS maakt gebruik van 32 verschillende registers. Hieronder een overzicht van de verschillende registers.
Registers :
| Naam | Nummer | Gebruik |
| $zero | $0 | Blijft steeds 0 |
| $at | $1 | Voorbehouden voor de assembler |
| $v0–$v1 | $2–$3 | Geeft de resultaten van functies |
| $a0–$a3 | $4–$7 | Functie-argumenten |
| $t0–$t7 | $8–$15 | Tijdelijke data |
| $s0–$s7 | $16–$23 | Opgeslagen tijdelijke data |
| $t8–$t9 | $24–$25 | Tijdelijke data |
| $k0–$k1 | $26–$27 | Voorbehouden voor de kernel van het besturingssysteem |
| $gp | $28 | Globale pointer |
| $sp | $29 | Stack pointer |
| $fp | $30 | Frame pointer |
| $ra | $31 | Terugkeeradres |
MIPS-instructies zijn 32 bits lang, zelfs bij de 64-bits processors. Dit zorgt voor een betere compatibiliteit met de 32-bits instructieset. Er is ook een mogelijkheid om via een extensie de processor een 16-bit instructieset te laten gebruiken. Dit wordt gebruikt wanneer de codelengte belangrijker is dan de performantie.
De MIPS-instructiesetarchitectuur is achterwaarts compatibel, dit wil zeggen dat een MIPS IV-processor nog steeds MIPS I-code kan uitvoeren.
De MIPS is een load/store-machine. De enige toegelaten geheugenoperaties zijn het laden van waarden in een van de registers of het opslaan van data vanuit een register in het geheugen.
Er zijn drie categorieën van instructies:
* Laad en opslag
** Laad data van het geheugen in een register, of sla een registerinhoud op in het geheugen.
** Vb.: lw $t0, num1 #laad woord van num1 in register $t0
* Wiskundige en logische bewerkingen
** Dit maakt het mogelijk wiskundige en logische bewerkingen uit te voeren.
** Vb.: add $t0, $t3, $t4 # $t0 = $t3 + $t4
* Jump en branch
** Wordt gebruikt om naar verschillende plaatsen in het programma te gaan.
** Voorbeeld: bij het gebruik van een IF-instructie.

### MIPS-instructieformaten

MIPS heeft drie instructieformaten.
| Type | -31-                formaat (bits)  -0- | -31-                formaat (bits)  -0- | -31-                formaat (bits)  -0- | -31-                formaat (bits)  -0- | -31-                formaat (bits)  -0- | -31-                formaat (bits)  -0- |
| R | opcode (6 bits) | rs (5 bits) | rt (5 bits | rd (5 bits) | shamt (5 bits) | funct (6 bits) |
| I | opcode (6 bits) | rs (5 bits) | rt (5 bits) | immediate (16 bits) | immediate (16 bits) | immediate (16 bits) |
| J | opcode (6 bits) | address (26 bits) | address (26 bits) | address (26 bits) | address (26 bits) | address (26 bits) |

## Pseudo-ops

Hieronder zijn enkele “pseudo-ops” of pseudo-operaties beschreven. Ze zullen het gedrag van de assembler mede bepalen. Gewone opcodes zijn processorgebonden terwijl pseudo-ops specifiek bij een bepaalde assembler horen omdat ze door de assembler zelf worden uitgevoerd.
| Pseudo-op | Beschrijving |
| .2byte expressie1[ , expressie2 ] … [ , expressieN] | Verkleint de expressies in de komma-gescheiden lijst (ook wel comma-separated list) naar 16-bits waarden en assembleert de waarden in overervende waarden. De expressies moeten absoluut zijn of, als de labels in dezelfde sectie zijn gedefinieerd, moeten ze gedefinieerd zijn in een verschil van labels(label1-label2). Deze richtlijn kan optioneel de vorm “expressie 1 [:expressie2] hebben. Wat betekent dat expressie 2 de waarde van expressie 1 twee keer kopieert. Deze richtlijn heeft geen automatische schikking (alleen maar 64-bit en N32) |
| .data | Zegt de assembler om alle volgende data bij de data sectie te zetten. |
| .end [proc_name] | Duidt het einde van een procedure aan. Gebruik deze verwijzing als je informatie wilt maken voor de debugger. |

## Adresseermethoden

Er zijn drie belangrijke manieren om naar data te verwijzen. Hieronder kan je zien hoe MIPS dit implementeert in zijn instructieformaten.

### Direct

De bronoperatoren kunnen constanten zijn. Een constante waarde wordt dan ook direct in machinetaalinstructies gecodeerd. Hierdoor is het adres onmiddellijk te bereiken nadat de instructie is gedecodeerd, zonder dat het adres uit het geheugen gehaald moet worden.
MIPS-instructies vertalen directe constanten in de 16 minst significante bits van de directe instructie-lay-out. Indien de constante groter is dan 16 bits zullen er twee machine-instructies worden gegenereerd. De meest significante cijfers worden dan geladen in het $at register met de “load upper immediate”-instructie.

### Registeradressering

Door het gebruik van registers als bron en bestemming van data worden de data sneller verwerkt dan bij het gebruik van geheugen. De meeste processoren hebben minstens één wiskundige instructieoperator nodig om register adressering te gebruiken. Instructies waarvan alle operators in registers zitten, zijn het snelst uit te voeren.
MIPS voorziet in 32 registers en vraagt om gebruik te maken van deze registers om data te verwerken. Omdat er maar 5 bits (2$^5$ = 32) nodig zijn om naar een register te verwijzen, is het gemakkelijk naar drie registers te verwijzen in een 32-bit-instructie.

### Geheugenadressering

Met 32-bits adressen kan een computer tot 4 GB geheugentoegang krijgen. Hierdoor kan je veel data opslaan, maar heb je ook meer tijd nodig om toegang te krijgen. In een MIPS-instructie kan je maximum naar één geheugenadres verwijzen. Net zoals in de meeste supercomputers beperkt MIPS dit tot laad- en opslaginstructies.

## De subroutine "Linkage" en Stacks
### MIPS call- en returnfunctie

Als we een functie (een procedure of een subroutine) oproepen, dan zouden we graag na de functie terugkeren naar de plaats waar we in de programmacode gebleven waren. Om dit te kunnen doen moeten we iets vinden om die plaats te onthouden. Er moet een standaard overeengekomen worden waar de terugkeerplaats wordt opgeslagen. MIPS gebruikt register 31 om dit adres in op te slaan. De functies die worden gebruikt om een functie op te roepen en terug te keren naar de oorspronkelijke instructie zijn:
* jal - jump and link: Hetzelfde formaat als jump maar als verschil dat jal het terugkeeradres opslaat in register 31, genoemd $ra of return address register.
* jr - jump register: In plaats van een vast doeladres te geven zoals een functienaam, springt deze instructie naar de locatie die is opgeslagen in register 31.
Als een klein voorbeeldje staat hieronder een functie om een integer af te drukken en een andere die een eindelijn-karakter afdrukt.
* Volledig overzicht van MIPS architectuur
* Paper over MIPS