# Lab2: RISC-V RV32I[MA] emulator with ELF support: Power Function ###### tags: `RISC-V` Choosing power function from [曾紹銘](https://hackmd.io/o1yeSGzDQO2LmbKXEoBC_g?view). ## Rewrite in C language ```cpp= void _start(){ volatile char* tx = (volatile char*) 0x40002000; int base = 3; int exp = 5; int result = 1; while(exp > 0){ if(exp & 0x1) result *= base; exp >>= 1; base *= base; } int out = result; *tx = out; } ``` ## Comparing different optimization and manual in GNU Toolchain ### execute the elf file The result in integer is not convert to char, so the output format is wrong. I was shocked by the counts of instruction. - produced by gcc with -O3 ```bash $ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -O3 -nostdlib -o pow power.c $ ./emu-rv32i pow � >>> Execution time: 19543 ns >>> Instruction count: 5 (IPS=255846) >>> Jumps: 1 (20.00%) - 0 forwards, 1 backwards >>> Branching T=0 (-nan%) F=0 (-nan%) ``` - produced by gcc with -Os I encountered some errors, but they have not been resolved. ```bash $ riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -Os -nostdlib -o pow power.c /home/ccs100203/riscv-none-embed-gcc/8.2.0-3.1/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld: /tmp/ccjM40Oy.o: in function `.L3': power.c:(.text+0x38): undefined reference to `__mulsi3' /home/ccs100203/riscv-none-embed-gcc/8.2.0-3.1/bin/../lib/gcc/riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld: /tmp/ccjM40Oy.o: in function `.L2': power.c:(.text+0x4c): undefined reference to `__mulsi3' collect2: error: ld returned 1 exit status ``` ### objdump ```bash $ riscv-none-embed-objdump -d pow ``` The optimization of gcc was amazing, the code size was greatly compressed. - produced by gcc with -O3 ``` pow: file format elf32-littleriscv Disassembly of section .text: 00010054 <_start>: 10054: 400027b7 lui a5,0x40002 10058: ff300713 li a4,-13 1005c: 00e78023 sb a4,0(a5) # 40002000 <__global_pointer$+0x3fff079c> 10060: 00008067 ret ``` - produced by manual ``` .data x: .word 3 y: .word 5 # unsigned str1: .string " ^ " str2: .string " = " .text main: lw s0, x # Set s0 equal to the parameter x lw s1, y # Set s1 equal to the parameter y mv a0, s0 # Set arguments mv a1, s1 jal power # return the result a0 mv s2, a0 # Set s2 equal to the result j print power: addi sp, sp, -12 sw ra, 0(sp) sw s0, 4(sp) sw s1, 8(sp) mv s0, a0 # s0 -> parameter x mv s1, a1 # s1 -> parameter y li s2, 1 # s2 -> res, init = 1 loop: bge x0, s1, Ret # if (0 >= y) break andi t0, s1, 0x1 # t0 -> y & 0x1 li t1, 0x1 # t1 -> 0x1 li ra, 0x54 # Set ra equal to srli s1, s1, 1 beq t0, t1, odd # y is odd srli s1, s1, 1 # y_u >> 1, y /= 2 mul s0, s0, s0 # x = x * x j loop # goto loop odd: mul s2, s2, s0 # res = res * x jr ra # goto srli s1, s1, 1 Ret: mv a0, s2 # Set return reg a0 lw ra, 0(sp) # Restore ra lw s0, 4(sp) # Restore s0 lw s1, 8(sp) # Restore s1 addi sp, sp, 12 # Free space on the stack for the 3 words jr ra # Return to the caller print: mv t0, a0 # Set tmp equal to a0 mv a0, s0 # prepare to print x li a7, 1 # print int ecall la a0, str1 # prepare to print string ^ li a7, 4 # print string ecall mv a0, s1 # prepare to print y li a7, 1 # print int ecall la a0, str2 # prepare to print string = li a7, 4 # print string ecall mv a0, s2 # prepare to print result li a7, 1 # print int ecall ``` ### readeif ```bash $ riscv-none-embed-readelf -h pow ``` - produced by gcc with -O3 ``` 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: 0x10054 Start of program headers: 52 (bytes into file) Start of section headers: 480 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 1 Size of section headers: 40 (bytes) Number of section headers: 6 Section header string table index: 5 ``` ### size ```bash $ riscv-none-embed-size pow ``` - produced by gcc with -O3 ``` text data bss dec hex filename 16 0 0 16 10 pow ```