일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 자동차 대여 기록에서 장기/단기 대여 구분하기 #프로그래머스 #DB #SQL #Mysql #DATE_ADD #TIMESTAMPDIFF
- 컴퓨터구조
- programmers
- 프로그래머스 #
- programmers #프로그래머스 #C언어
- instrction
- 명령어
- pseudo
- 조건부 분기
- 네트워크 #network #운영체제 #OS #면접대비 #대학원 #
- SQL 문법 #SQL #테이블 #스키마 #스키마스 #데이테베이스 #공부
- git bash
- 조건에 부합하는 중고거래 댓글 조회하기 #SQL #Mysql
- RV32I
- J-type
- 산술연산
- RISC-V
- Computer Architecture
- 특정 옵션이 포함된 자동차 리스트 구하기 #programmers #프로그래머스 #SQL #Mysql
- Git 초보
- shift연산
- 분기 명령어
- 메모리접근
- 비교연산
- 프로세스 #스레드 #컨텍스트스위칭 #프로그램기초 #IT
- SQL #MySQL #데이터베이스 #database #프로그래밍 #DDL #DML #TCL #DB #DBMS #RDBMS
- git error 해결
- instruction
- SQL #RDBMS #테이블 #table #row #column #문자형 데이터 #숫자형 데이터 #날짜형 데이터 #관계형 데이터베이스 #DB #데이터베이스 #database #MYSQL #MYSQL 설치 #MYSQL 접속
- 무조건 분기
- Today
- Total
juniverse
[RISC-V] RV32I 분기 명령어 본문
[RISC-V] RV32I 분기 명령어
iamjunis 2022. 7. 21. 00:20분기 명령어에는 조건에 따른 분기 conditional branch 명령어와 무조건 분기 unconditional branch 명령어 두 종류가 있다.
branch 명령어의 실행 결과를 말할 때 taken 또는 not-taken과 같은 용어를 자주 사용하는데,
'beq x3, x4, L1'의 예에서 x3 == x4이면 branch가 taken 됐다고 말하고, 그렇지 않으면 not-taken 됐다고 말한다.
# conditional branch / B-type
- beq rs1, rs2, imm[12:1]
beq x10, x11, L1 // if (x10 == x11) PC → L1;
// else PC → PC + 4;
- bne rs1, rs2, imm[12:1]
bne x10, x11, L1 // if (x10 ≠ x11) PC → L1;
// else PC → PC + 4;
- blt rs1, rs2, imm[12:1]
blt x10, x11, L1 // x10, x11 : signed 정수
// if (x10 < x11) PC → L1;
// else PC → PC + 4;
- bltu rs1, rs2, imm[12:1]
bltu x10, x11, L1 // x10, x11 : unsigned 정수
// if (x10 < x11) PC → L1;
// else PC → PC + 4;
- bge rs1, rs2, imm[12:1]
bge x10, x11, L1 // x10, x11 : signed 정수
// if (x10 ≥ x11) PC → L1;
// else PC → PC + 4;
- bgeu rs1, rs2, imm[12:1]
bgeu x10, x11, L1 // x10, x11 : unsigned 정수
// if (x10 ≥ x11) PC → L1;
// else PC → PC + 4;
BEQ : equal
BNE : not equal
BLT / BLTU : less than, greater than
BGE / BGEU : less than equal, greater than equal
이렇게 보면, signed와 unsigned가 헷갈릴 수 있어 Pseudo 명령어를 이용해 표로 정리해보았다.
Data type | 비교 | Pseudo 명령어 | 실제 명령어 |
Unsigned | a == b | beq a, b, label | |
a != b | bne a, b, label | ||
a > b | bgtu a, b, label | bltu b, a, label | |
a ≥ b | bgeu a, b, label | ||
a < b | bltu a, b, label | ||
a ≤ b | bleu a, b, label | bgeu b, a, label | |
Signed | a == b | beq a, b, label | |
a != b | bne a, b, label | ||
a > b | bgt a, b, label | blt b, a, label | |
a ≥ b | bge a, b, label | ||
a < b | blt a, b, label | ||
a ≤ b | ble a, b, label | bge b, a, label |
Signed 정수 a,b에 대해 'a>b' 조건을 판단하려면 pseudo 명령어인 'bgt a, b, L1'을 사용하면 된다.
그러면 컴파일러가 그것을 'blt b, a, L1' 명령어로 바꿔준다.
Unsigned 정수 a,b에 대해 'a≤b' 조건을 판단하려면 pseudo 면령어인 'bleu a, b, L1'을 사용하면 된다.
그러면 컴파일러가 그것을 'bleu b, a, L1' 명령어로 바꿔준다.
# unconditional branch
무조건 분기 명령어와 함께 주로 쌍으로 사용되는 명령어 lui, auipc 명령어가 있다.
* U-type / lui, auipc
- lui rd, imm[31:12] // load upper immediate
lui x10, 0x12345 // x10 = 0x1234_5000
레지스터의 상위 20-bit를 특정 값으로 채울 때 사용하는데,
immediate에 있는 20-bit 값을 destination 레지스터의 위쪽에 채우고 아래쪽 12-bit는 0으로 채운다.
- auipc rd, imm[31:12] // add upper immediate to PC
auipc x10, 0x12345 ]\// x10 = current PC + 0x1234_5000
lui 동작과 비슷한데, 차이는 'auipc 명령어의 PC'를 더한 값으로 레지스터를 채운다는 것이다.
주로 레지스터의 상위 20-bit를 특정 값으로 채울 때 사용하는데,
PC-relative 주소를 만들 때 주로 사용한다. 현재 PC에서 offset만큼 떨어진 곳,
즉 relative하게 떨어져 있는 곳의 주소를 레지스터에 저장하기 위해 사용한다.
1) J-type
- jal rd, imm[20:1]
jal ra, foo // foo() 함수 호출
// PC ← L1;
// ra(=x1) ← PC + 4;
PC-relative 방식으로, 분기하려는 목적지가 현재 명령어 위치에서 immediate만큼 떨어져 있는 direct jump 명령어이다.
2) I-type
- jalr rd, imm[20:1]
jalr ra, 8(x4) // PC ← x4 +8;
// ra(=x1) ← PC + 4;
목적지가 레지스터 값에서 immediate만큼 떨어져 있는 indirect jump 명령어이다.
* indirect : 분기할 목적지가 명령어에 직접적으로 명시되는 것이 아니라 레지스터를 통해 간접적으로 명시되는 것
※ indirect jump를 제공하는 이유?
1) 호출하는 함수의 위치가 너무 멀어 jal 명령어로 도달할 수 없을 수 있기 때문이다.
- jalr 명령어는 레지스터를 통해 32-bit 주소 공간에서 목적지가 어디든 분기할 수 있다.
2) 호출할 함수가 '실행 중' 결정되는 것을 지원하기 위해서이다.
JAL : jump and link
JALR : jump and link register
RV32I는 unconditional 분기 명령어로 jal와 jalr 명령어 두 개만을 제공하지만 프로그래밍을 통해 직관적으로 사용할 수 있는 다양한 pseudo 명령어를 만들 수 있다.
Pseudo 명령어 | 실제 명령어 | |
Jump | j offset | jal x0, offset |
Jump and link | jal offset | jal x1, offset |
Jump register | jr rs | jalr x0, 0(rs) |
Jump and link register | jalr rs | jalr x1, 0(rs) |
Return from function | ret | jair x0,0(x1) |
Call function | call offset | auipc x1, offset[31:12] + offset[11] jalr x1 offset[11:0](x1) |
# Reference
원리부터 설계까지 쉽고 명확한 컴퓨터구조 RISC-V 중심으로 - 서태원 지음 - 도서출판 홍릉
'컴퓨터구조 computer organization and design > RISC-V edition' 카테고리의 다른 글
[RISC-V] Pseudo Instruction (0) | 2022.07.21 |
---|---|
[RISC-V] RV32I 메모리접근 명령어 (0) | 2022.07.20 |
[RISC-V] RV32I 데이터처리 명령어 (0) | 2022.07.20 |
[RISC-V] RV32I Instruction Set (0) | 2022.07.20 |