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