1 개요
MIPS(Microprocessor without Interlocked Pipeline Stages)란 MIPS Technologies에서 개발한 RISC기반의 명령어 집합 체계이다.
MIPS 명령어 체계는 많은 대학교의 컴퓨터 아키텍처 강좌에서 사용되고 있다.
2 MIPS의 역사
최초의 MIPS 명령어 체계는 MIPS Computer Systems(현 MIPS Technologies)에서 발표한 R2000 마이크로프로세서와 함께 MIPS I이라는 이름으로 발표되었다. 당시 R2000은 RISC기반의 명령어가 처음으로 적용되어 상용화 된 CPU이다. 그 당시에 R2000은 모토롤라 68000이나 인텔 80386 시리즈와 경쟁했다. MIPS 명령어체계는 MIPS Technologies에서 새로운 CPU를 출시할때마다 개선이 이루어졌는데, 1990년에는 R6000과 함께 MIPS II가 발표되었고, 1992년에는 64bit 레지스터와 정수연산이 지원되는 MIPS III가 발표되었다. 1994년에는 MIPS IV가 발표되었고, 1996년도에 MIPS V가 발표되었으며, 현재 존재하는 MIPS 명령어 체계는 전부 MIPS V를 기반으로 개선이 이루어지고 있는 상태이다. 가장 최신 버전의 MIPS 명령어 체계는 MIPS V를 기반으로 한 MIPS32 release 5로, 2012년에 발표되었다.
MIPS Technologies는 2000년대 중후반부터 뛰어난 전력효율을 기반으로 스마트 시대와 맞물려 시장을 넓혀온 ARM에 입지를 잃어가다가 결국 2012년 말 Apple의 iOS기기용 GPU인 PowerVR 시리즈로 유명한 Imagination Technology에 인수되었다. 관련기사[1][2]
3 MIPS 명령어 체계
MIPS 명령어 체계[3]는 3가지 타입의 명령어(R타입[4], I타입[5], J타입[6]) 명렁어로 나뉘어진다.
MIPS 명령어 체계를 확장한 명령어 체계로는 MCU, SmartMIPS, MDMX, MIPS-3D, microMIPS, picoMIPS, MIPS16e등이 있다.
3.1 16bit picoMIPS
32bit MIPS 명령어 체계를 알아보기에 앞서, 16bit picoMIPS[7]를 기반으로 한 명령어 체계를 통해 MIPS 명령어 체계를 이해 할 필요가 있다. 16bit picoMIPS는 총 16bit의 길이를 가지게 되며, 일반적으로 8개의 레지스터를 사용하기 때문에 3bit로 레지스터 주소를 표현하게 된다. 위에 나와있는 명령어 타입별로 각각 살펴보면
R타입 명령어 | ||||
4bit opcode | 3bit rs | 3bit rt | 3bit rd | 3bit funct[8] |
I타입 명령어 | ||||
4bit opcode | 3bit rs | 3bit rt[9] | 6bit immediate | |
J타입 명령어 | ||||
4bit opcode | 12bit address |
로 이루어지게 된다.
이제 간단한 16bit picoMIPS의 연산을 하나 살펴보도록 하자. R타입 명령어로 덧셈 연산을 한다고 가정을 하여, 0번 레지스터의 값과 1번 레지스터의 값을 더해서 2번 레지스터에 값에 기록한다고 가정하자.[10] 이때 덧셈 연산의 funct값이 000이라고 가정하면
0000 000 001 010 000와 같이 표현을 할 수 있다. R타입 명령어의 opcode값은 항상 0이므로 앞의 4bit는 0이되며, rs, rt, rd에는 사용할 레지스터의 값을 넣으며, 마지막 3bit에는 실행할 연산인 덧셈의 funct값인 000을 넣게 된다.
다음으로는 J타입 명령어의 연산을 하나 가정해보도록 하겠다. 3번 레지스터에 있는 값과 임의의 즉치값 15를 더한 값을 4번 레지스터에 기록하며, 이때 덧셈의 opcode가 1000이면
1000 011 100 001111와 같이 표현을 할 수 있다. J타입 명령어는 rt에 계산 결과가 기록되고, 이 rt가 rs와 즉치값 사이에 들어온다.
3.2 32bit MIPS
32bit MIPS 명령어 체계도 16bit picoMIPS 명령어와 동일하게 R타입 명령어, I타입 명령어, J타입 명령어로 나뉘어진다. 32bit MIPS는 총 32bit의 길이를 가지게 되며, 일반적으로 32개의 레지스터를 사용하기 때문에 5bit로 레지스터 주소를 표현하게 된다. 명령어 타입별로 각각 살펴보면
R타입 명령어 | |||||
6bit opcode | 5bit rs | 5bit rt | 5bit rd | 5bit shamt[11] | 6bit funct |
I타입 명령어 | |||||
6bit opcode | 5bit rs | 5bit rt | 16bit immediate | ||
J타입 명령어 | |||||
6bit opcode | 26bit address |
로 이루어져 있다.
4 MIPS 레지스터의 호출 규약
MIPS 레지스터의 호출 규약은 일반적으로 사용되는 O32 ABI와 N64/N32 ABI로 나뉘어진다. O32 ABI는 32bit CPU를 위한 레지스터 호출 규약이며, N64/N32 ABI는 64bit CPU를 위한 레지스터 호출규약이다. 기본적인 레지스터 호출 규약은 다음과 같다.
이름 | 레지스터 번호 | 용도 |
$zero | $0 | 항상 0을 출력하는 레지스터. 이 레지스터의 값은 바꿀 수 없다 |
$at | $1 | 의사 명령어(특정 조건 만족시 분기 명령어) 계산 결과를 위해 예약된 레지스터 |
$v0 ~ $v1 | $2 ~ $3 | 함수로부터 반환된 값을 저장하는 레지스터 |
$a0 ~ $a3 | $4 ~ $7 | 함수 인수 저장용 레지스터 |
$t0 ~ $t7 | $8 ~ $15 | 어셈블러나 어셈블리 언어에서 값을 임시로 저장할때 사용하는 레지스터 |
$s0 ~ $s7 | $16 ~ $23 | 오랫동안 지속되는 값을 저장할때 사용하는 레지스터 |
$t8 ~ $t9 | $24 ~ $25 | 어셈블러나 어셈블리 언어에서 값을 임시로 저장할때 사용하는 레지스터 |
$k0 ~ $k1 | $26 ~ $27 | OS 커널을 위해 예약된 레지스터 |
$gp | $28 | 전역 포인터의 값을 저장하는 레지스터 |
$sp | $29 | 스택 포인터의 값을 저장하는 레지스터 |
$fa | $30 | 프레임 포인터의 값을 저장하는 레지스터 |
$ra | $31 | 주소 반환값을 저장하는 레지스터 |
5 기타
이 아키텍처를 사용하는 게임기로는 플레이스테이션, 닌텐도 64, 하이퍼 네오지오 64, 플레이스테이션 2, PSP가 있다.- ↑ 그리고 2016년 3월에
애플만 바라보며 먹고살던이매지네이션에서 경영악화를 겪고 있으며 애플에서 이를 인수할 것이라는 루머가 돌고 있다. - ↑ 애플에서 MIPS를 품은 이매지네이션을 인수하면 애플에서는 ARM 코어의 자체설계 라이선스에 더해 MIPS의 CPU, 이매지네이션의 GPU 관련 기술까지 모두 흡수하게 된다.
- ↑ 들어가기에 앞서 opcode라는 개념에 대해서 알아야 할 필요가 있다. opcode는 해당 명령어가 실행할 연산의 종류를 정의한다.
- ↑ c = a + b와 같은 연산을 할때, 2개의 레지스터 값을 이용하여 연산을 한 다음, 다른 레지스터 하나에 연산한 값을 기록한다. 이때 연산을 하는데 사용되는 레지스터는 각각 rs(register source의 약자), rt(register target의 약자)로 불리게 되며, 연산을 한 값을 rd(register direction의 약자)에 저장하게 된다.
- ↑ R타입과 비슷하게 두개의 값을 이용해 연산을 한 다음 다른 하나의 레지스터에 저장을 하지만, 연산할 값을 하나는 레지스터에서 가져오고 다른 하나는 레지스터가 아니라 지정된 임의의 값을 사용한다. I타입 명령어에서 c = a + b와 같은 연산을 수행한다 하면, 이때 b는 레지스터에 없는 임의의 값이 된다. R타입 명령어에 있는 약자인 rs와 rt를 그대로 사용하며, 이때 사용되는 임의의 값은 immediate(줄여서 imm이라고도 하며, 즉치값이라고도 부른다.)로 부른다. 계산은 rt = rs + imm로 한다.
- ↑ 무조건 분기 명령어로, 특정 메모리 주소로 바로 이동이 필요한 경우에 사용되는 명령어다. 이동할 메모리 주소를 연산에 사용한다
- ↑ MIPS 명령어 체계를 매우 축소했다는 의미로, 접두사에 pico가 붙는다. 일부를 축소한 microMIPS는 32bit/64bit 명령어 체계이다.
- ↑ 명령어가 실행할 연산의 종류는 opcode에서 정의가 되어있는 상태이지만, 이 경우 opcode만으로는 충분한 연산의 종류를 정의할 수 없는 경우가 발생하게 된다. 이것에 대한 해결 방안으로 사용되는 것이 function(이를 줄여서 funct라고 한다.) 코드값이다. opcode의 값이 전부 0으로 채워져 있으면, 해당 명령어의 타입을 무조건 R타입으로 인식을 시키게 한 다음, funct값을 확인해서 연산을 하는 방법을 정하게 된다. 이 방법을 통해 제한된 비트 안에서 최대한 많은 종류의 연산을 할 수 있게 된다.
- ↑ 여기서 주의해야 되는 것이 하나 있는데, R타입 명령어는 앞에 있는 두개의 레지스터 값을 이용해 뒤에 있는 rd에 저장을 하게 되지만, I타입 명령어에서는 가운데에 있는 rt에 저장을 하게 된다는 것이다.
- ↑ 이해를 돕기 위해, 모든 레지스터에 임의로 접근이 가능하다고 가정하였다. MIPS 명령어 체계에서는 사용자가 접근할 수 없는 레지스터가 있다.
- ↑ shift amout의 약자. 비트 시프트 연산용이다.