---
title: Lab2:RISC-V Toolchain
tags: RISCV
---
## Lab2: RISC-V Toolchain
* Motivation: 想要學習 struct 與 linked list 的寫法
```c=
#include <stdio.h>
#include <stdlib.h>
struct node{
int val;
struct node* next;
};
const int nums[] = {1, 0, 3};
const int numsSize = 3;
void create_list(struct node** cur)
{
for (int i = 0; i < numsSize; ++i) {
struct node* n = malloc(sizeof(struct node));
n->val = nums[i];
n->next = NULL;
(*cur) = n;
cur = &((*cur)->next);
}
}
void print_list(struct node* head)
{
struct node* cur = head;
while (cur) {
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
}
int main()
{
struct node* head = NULL;
create_list(&head);
print_list(head);
return 0;
}
```
## Using RISC-V gcc
* 更新環境變數
> $ source riscv-none-elf-gcc/setenv
* 編譯
> $ riscv-none-elf-gcc -march=rv32i -mabi=ilp32 -o test test.c
* -march=rv32i : Specify RV32I instruction set architecture
* -mabi=ilp32 : Specify [ILP32 ABI](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc)
* 反組譯並存成txt
> riscv-none-elf-objdump -d ./test > test.txt
* 看elf標頭
> riscv-none-elf-readelf -h ./test
```
will@will:~/rv32emu/HW$ riscv-none-elf-readelf -h ./test
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x100dc
Start of program headers: 52 (bytes into file)
Start of section headers: 95292 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 15
Section header string table index: 14
```
* 看size
> riscv-none-elf-size ./test
```
will@will:~/rv32emu/HW$ riscv-none-elf-size ./test
text data bss dec hex filename
75400 2820 812 79032 134b8 ./test
```
* 執行code
> build/rv32emu test
```
will@will:~/rv32emu$ build/rv32emu HW/test
1 0 3
inferior exit code 0
```
## Compare Assembly Code
### -O1 Optimized Assembly Code
```c=
will@will:~/rv32emu/HW$ riscv-none-elf-size ./test
text data bss dec hex filename
75300 2820 812 78932 13454 ./test
```
* Assembly code
```c=
00010184 <create_list>:
10184: ff010113 addi sp,sp,-16
10188: 00112623 sw ra,12(sp)
1018c: 00812423 sw s0,8(sp)
10190: 00912223 sw s1,4(sp)
10194: 00050413 mv s0,a0
10198: 00800513 li a0,8
1019c: 1d4000ef jal ra,10370 <malloc>
101a0: 00050493 mv s1,a0
101a4: 00100793 li a5,1
101a8: 00f52023 sw a5,0(a0)
101ac: 00052223 sw zero,4(a0)
101b0: 00a42023 sw a0,0(s0)
101b4: 00800513 li a0,8
101b8: 1b8000ef jal ra,10370 <malloc>
101bc: 00050413 mv s0,a0
101c0: 00052023 sw zero,0(a0)
101c4: 00052223 sw zero,4(a0)
101c8: 00a4a223 sw a0,4(s1)
101cc: 00800513 li a0,8
101d0: 1a0000ef jal ra,10370 <malloc>
101d4: 00300793 li a5,3
101d8: 00f52023 sw a5,0(a0)
101dc: 00052223 sw zero,4(a0)
101e0: 00a42223 sw a0,4(s0)
101e4: 00c12083 lw ra,12(sp)
101e8: 00812403 lw s0,8(sp)
101ec: 00412483 lw s1,4(sp)
101f0: 01010113 addi sp,sp,16
101f4: 00008067 ret
000101f8 <print_list>:
101f8: ff010113 addi sp,sp,-16
101fc: 00112623 sw ra,12(sp)
10200: 00812423 sw s0,8(sp)
10204: 00912223 sw s1,4(sp)
10208: 02050063 beqz a0,10228 <print_list+0x30>
1020c: 00050413 mv s0,a0
10210: 000224b7 lui s1,0x22
10214: 00042583 lw a1,0(s0)
10218: 90848513 addi a0,s1,-1784 # 21908 <__clzsi2+0x88>
1021c: 219000ef jal ra,10c34 <printf>
10220: 00442403 lw s0,4(s0)
10224: fe0418e3 bnez s0,10214 <print_list+0x1c>
10228: 00a00513 li a0,10
1022c: 25d000ef jal ra,10c88 <putchar>
10230: 00c12083 lw ra,12(sp)
10234: 00812403 lw s0,8(sp)
10238: 00412483 lw s1,4(sp)
1023c: 01010113 addi sp,sp,16
10240: 00008067 ret
00010244 <main>:
10244: fe010113 addi sp,sp,-32
10248: 00112e23 sw ra,28(sp)
1024c: 00c10513 addi a0,sp,12
10250: f35ff0ef jal ra,10184 <create_list>
10254: 00c12503 lw a0,12(sp)
10258: fa1ff0ef jal ra,101f8 <print_list>
1025c: 00000513 li a0,0
10260: 01c12083 lw ra,28(sp)
10264: 02010113 addi sp,sp,32
10268: 00008067 ret
```
* Observation
* LOC(line of code) : ```61```
* create_list: Allocate ```16``` bytes on stack
* Number of registers used : ```$ra```, ```$sp```, ```$s0 ~ $s1```, ```$a0```、```$a1```、```$a5```
* Number of lw and sw used : ```10``` and ```16```
* Execution & CSR count
```c=
will@will:~/rv32emu$ build/rv32emu --stats HW/test
1 0 3
inferior exit code 0
CSR cycle count: 3208
```
### -O2 Optimized Assembly Code
```c=
will@will:~/rv32emu/HW$ riscv-none-elf-size ./test
text data bss dec hex filename
75304 2820 812 78936 13458 ./test
```
* Assembly code
```c=
000100c4 <main>:
100c4: fe010113 addi sp,sp,-32
100c8: 00c10513 addi a0,sp,12
100cc: 00112e23 sw ra,28(sp)
100d0: 0dc000ef jal ra,101ac <create_list>
100d4: 00c12503 lw a0,12(sp)
100d8: 148000ef jal ra,10220 <print_list>
100dc: 01c12083 lw ra,28(sp)
100e0: 00000513 li a0,0
100e4: 02010113 addi sp,sp,32
100e8: 00008067 ret
000101ac <create_list>:
101ac: ff010113 addi sp,sp,-16
101b0: 00812423 sw s0,8(sp)
101b4: 00050413 mv s0,a0
101b8: 00800513 li a0,8
101bc: 00112623 sw ra,12(sp)
101c0: 00912223 sw s1,4(sp)
101c4: 1b0000ef jal ra,10374 <malloc>
101c8: 00050493 mv s1,a0
101cc: 00100793 li a5,1
101d0: 00f4a023 sw a5,0(s1)
101d4: 00a42023 sw a0,0(s0)
101d8: 0004a223 sw zero,4(s1)
101dc: 00800513 li a0,8
101e0: 194000ef jal ra,10374 <malloc>
101e4: 00050413 mv s0,a0
101e8: 00042023 sw zero,0(s0)
101ec: 00042223 sw zero,4(s0)
101f0: 0084a223 sw s0,4(s1)
101f4: 00800513 li a0,8
101f8: 17c000ef jal ra,10374 <malloc>
101fc: 00300793 li a5,3
10200: 00f52023 sw a5,0(a0)
10204: 00052223 sw zero,4(a0)
10208: 00c12083 lw ra,12(sp)
1020c: 00a42223 sw a0,4(s0)
10210: 00812403 lw s0,8(sp)
10214: 00412483 lw s1,4(sp)
10218: 01010113 addi sp,sp,16
1021c: 00008067 ret
00010220 <print_list>:
10220: 04050463 beqz a0,10268 <print_list+0x48>
10224: ff010113 addi sp,sp,-16
10228: 00812423 sw s0,8(sp)
1022c: 00912223 sw s1,4(sp)
10230: 00112623 sw ra,12(sp)
10234: 00050413 mv s0,a0
10238: 000224b7 lui s1,0x22
1023c: 00042583 lw a1,0(s0)
10240: 91048513 addi a0,s1,-1776 # 21910 <__clzsi2+0x8c>
10244: 1f5000ef jal ra,10c38 <printf>
10248: 00442403 lw s0,4(s0)
1024c: fe0418e3 bnez s0,1023c <print_list+0x1c>
10250: 00812403 lw s0,8(sp)
10254: 00c12083 lw ra,12(sp)
10258: 00412483 lw s1,4(sp)
1025c: 00a00513 li a0,10
10260: 01010113 addi sp,sp,16
10264: 2290006f j 10c8c <putchar>
10268: 00a00513 li a0,10
1026c: 2210006f j 10c8c <putchar>
```
* Observation
* LOC(line of code) : ```62```
* create_list: Allocate ```16``` bytes on stack
* Number of registers used : ```$ra```, ```$sp``` , ```$s0~$s1```, ```$a0```、```$a1```、```$a5```
* Number of lw and sw used : ```10``` and ```16```
* Execution & CSR count
```c=
will@will:~/rv32emu$ build/rv32emu --stats HW/test
1 0 3
inferior exit code 0
CSR cycle count: 3208
```
### -O3 Optimized Assembly Code
```c=
will@will:~/rv32emu/HW$ riscv-none-elf-size ./test
text data bss dec hex filename
75304 2820 812 78936 13458 ./test
```
* Assembly code
```c=
000100c4 <main>:
100c4: fe010113 addi sp,sp,-32
100c8: 00c10513 addi a0,sp,12
100cc: 00112e23 sw ra,28(sp)
100d0: 0dc000ef jal ra,101ac <create_list>
100d4: 00c12503 lw a0,12(sp)
100d8: 148000ef jal ra,10220 <print_list>
100dc: 01c12083 lw ra,28(sp)
100e0: 00000513 li a0,0
100e4: 02010113 addi sp,sp,32
100e8: 00008067 ret
000101ac <create_list>:
101ac: ff010113 addi sp,sp,-16
101b0: 00812423 sw s0,8(sp)
101b4: 00050413 mv s0,a0
101b8: 00800513 li a0,8
101bc: 00112623 sw ra,12(sp)
101c0: 00912223 sw s1,4(sp)
101c4: 1b0000ef jal ra,10374 <malloc>
101c8: 00050493 mv s1,a0
101cc: 00100793 li a5,1
101d0: 00f4a023 sw a5,0(s1)
101d4: 00a42023 sw a0,0(s0)
101d8: 0004a223 sw zero,4(s1)
101dc: 00800513 li a0,8
101e0: 194000ef jal ra,10374 <malloc>
101e4: 00050413 mv s0,a0
101e8: 00042023 sw zero,0(s0)
101ec: 00042223 sw zero,4(s0)
101f0: 0084a223 sw s0,4(s1)
101f4: 00800513 li a0,8
101f8: 17c000ef jal ra,10374 <malloc>
101fc: 00300793 li a5,3
10200: 00f52023 sw a5,0(a0)
10204: 00052223 sw zero,4(a0)
10208: 00c12083 lw ra,12(sp)
1020c: 00a42223 sw a0,4(s0)
10210: 00812403 lw s0,8(sp)
10214: 00412483 lw s1,4(sp)
10218: 01010113 addi sp,sp,16
1021c: 00008067 ret
00010220 <print_list>:
10220: 04050463 beqz a0,10268 <print_list+0x48>
10224: ff010113 addi sp,sp,-16
10228: 00812423 sw s0,8(sp)
1022c: 00912223 sw s1,4(sp)
10230: 00112623 sw ra,12(sp)
10234: 00050413 mv s0,a0
10238: 000224b7 lui s1,0x22
1023c: 00042583 lw a1,0(s0)
10240: 91048513 addi a0,s1,-1776 # 21910 <__clzsi2+0x8c>
10244: 1f5000ef jal ra,10c38 <printf>
10248: 00442403 lw s0,4(s0)
1024c: fe0418e3 bnez s0,1023c <print_list+0x1c>
10250: 00812403 lw s0,8(sp)
10254: 00c12083 lw ra,12(sp)
10258: 00412483 lw s1,4(sp)
1025c: 00a00513 li a0,10
10260: 01010113 addi sp,sp,16
10264: 2290006f j 10c8c <putchar>
10268: 00a00513 li a0,10
1026c: 2210006f j 10c8c <putchar>
```
* Observation
* LOC(line of code) : ```62```
* create_list: Allocate ```16``` bytes on stack
* Number of registers used : ```$ra```, ```$sp``` , ```$s0~$s1```, ```$a0```、```$a1```、```$a5```
* Number of lw and sw used : ```10``` and ```16```
* Execution & CSR count
```c=
will@will:~/rv32emu$ build/rv32emu --stats HW/test
1 0 3
inferior exit code 0
CSR cycle count: 3208
```
### -Os Optimized Assembly Code
```c=
will@will:~/rv32emu/HW$ riscv-none-elf-size ./test
text data bss dec hex filename
75296 2820 812 78928 13450 ./test
```
* Assembly code
```c=
000100c4 <main>:
100c4: fe010113 addi sp,sp,-32
100c8: 00c10513 addi a0,sp,12
100cc: 00112e23 sw ra,28(sp)
100d0: 0dc000ef jal ra,101ac <create_list>
100d4: 00c12503 lw a0,12(sp)
100d8: 148000ef jal ra,10220 <print_list>
100dc: 01c12083 lw ra,28(sp)
100e0: 00000513 li a0,0
100e4: 02010113 addi sp,sp,32
100e8: 00008067 ret
000101ac <create_list>:
101ac: ff010113 addi sp,sp,-16
101b0: 00812423 sw s0,8(sp)
101b4: 00050413 mv s0,a0
101b8: 00800513 li a0,8
101bc: 00112623 sw ra,12(sp)
101c0: 00912223 sw s1,4(sp)
101c4: 1a8000ef jal ra,1036c <malloc>
101c8: 00100793 li a5,1
101cc: 00f52023 sw a5,0(a0)
101d0: 00050493 mv s1,a0
101d4: 00a42023 sw a0,0(s0)
101d8: 00052223 sw zero,4(a0)
101dc: 00800513 li a0,8
101e0: 18c000ef jal ra,1036c <malloc>
101e4: 00052023 sw zero,0(a0)
101e8: 00052223 sw zero,4(a0)
101ec: 00050413 mv s0,a0
101f0: 00a4a223 sw a0,4(s1)
101f4: 00800513 li a0,8
101f8: 174000ef jal ra,1036c <malloc>
101fc: 00300793 li a5,3
10200: 00f52023 sw a5,0(a0)
10204: 00052223 sw zero,4(a0)
10208: 00c12083 lw ra,12(sp)
1020c: 00a42223 sw a0,4(s0)
10210: 00812403 lw s0,8(sp)
10214: 00412483 lw s1,4(sp)
10218: 01010113 addi sp,sp,16
1021c: 00008067 ret
00010220 <print_list>:
10220: ff010113 addi sp,sp,-16
10224: 00812423 sw s0,8(sp)
10228: 00912223 sw s1,4(sp)
1022c: 00112623 sw ra,12(sp)
10230: 00050413 mv s0,a0
10234: 000224b7 lui s1,0x22
10238: 00041e63 bnez s0,10254 <print_list+0x34>
1023c: 00812403 lw s0,8(sp)
10240: 00c12083 lw ra,12(sp)
10244: 00412483 lw s1,4(sp)
10248: 00a00513 li a0,10
1024c: 01010113 addi sp,sp,16
10250: 2350006f j 10c84 <putchar>
10254: 00042583 lw a1,0(s0)
10258: 90848513 addi a0,s1,-1784 # 21908 <__clzsi2+0x8c>
1025c: 1d5000ef jal ra,10c30 <printf>
10260: 00442403 lw s0,4(s0)
10264: fd5ff06f j 10238 <print_list+0x18>
```
* Observation
* LOC(line of code) : ```60```
* create_list: Allocate ```16``` bytes on stack
* Number of registers used : ```$ra```, ```$sp``` , ```$s0~$s1```, ```$a0```、```$a1```、```$a5```
* Number of lw and sw used : ```10``` and ```16```
* Execution & CSR count
```c=
will@will:~/rv32emu$ build/rv32emu --stats HW/test
1 0 3
inferior exit code 0
CSR cycle count: 3208
```
### Summary
I have learned a lot of optimization methods for combined languages in this assignment. We can see that ==loop unrooling== will shorten the execution time, but it will not reduce the number of CSRs used. Maybe in the future I can use more optimized ways to deal with the above program