# RISC-V Toolchain 2
###### tags: `Computer Architecture 2020`
## [GCD (Greatest Common Divisor)](https://hackmd.io/@cccccs100203/lab1-RISC-V)
The following assembly program was implemented by 洪邵澤同學.
### RISC-V asm with recursion
```clike=
.data
in1: .word 24
in2: .word 16
.text
main:
lw a0, in1
lw a1, in2
jal GCD
li a7,1
ecall
j end
GCD:
beqz a1,return # if(a1 = 0) t0 = 0;
#blt a0, a1, swap # if(a0 > a1) goto SWAP;
rem a0, a0, a1 # a0 = a0 % a1;
swap:
mv t1, a0
mv a0, a1
mv a1, t1
j GCD
return:
jr ra
end:
```
### Rewrite in C
int main() was replaced by void _start() and mod was added manually, and print the result on console in binary.
```c=
int gcd(int u, int v);
unsigned int mod(unsigned int a, unsigned int b);
void _start() {
volatile int n = gcd(1840564, 836620);
volatile char *tx = (volatile char *)0x40002000;
unsigned int i;
for (i = 0x80000000; i; i >>= 1) {
*tx = ('0' + ((i & n) ? 1 : 0));
}
}
int gcd(int u, int v){
int tmp;
while (v) {
tmp = v;
v = mod(u, v);
u = tmp;
}
return u;
}
unsigned int mod(unsigned int a, unsigned int b){
unsigned long long rem = 0x00000000ffffffff & a;
signed long long bHigh = (signed long long)b << 32;
int count = 32;
rem <<= 1;
while (count--) {
if ((signed long long)rem - bHigh >= 0) {
rem -= bHigh;
}
rem <<= 1;
}
return rem >> 33;
}
```
### Run with rv32emu emulator
#### Check the answer with no optimization and all optimization
- O0
```
00000000000000101000110110011100
>>> Execution time: 192807 ns
>>> Instruction count: 2330 (IPS=12084623)
>>> Jumps: 202 (8.67%) - 100 forwards, 102 backwards
>>> Branching T=182 (91.92%) F=16 (8.08%)
```
- O1
```
00000000000000101000110110011100
>>> Execution time: 107683 ns
>>> Instruction count: 1025 (IPS=9518679)
>>> Jumps: 108 (10.54%) - 8 forwards, 100 backwards
>>> Branching T=96 (58.90%) F=67 (41.10%)
```
- O2
```
00000000000000101000110110011100
>>> Execution time: 116926 ns
>>> Instruction count: 797 (IPS=6816276)
>>> Jumps: 157 (19.70%) - 62 forwards, 95 backwards
>>> Branching T=155 (95.68%) F=7 (4.32%)
```
- O3
```
00000000000000101000110110011100
>>> Execution time: 86595 ns
>>> Instruction count: 767 (IPS=8857324)
>>> Jumps: 181 (23.60%) - 85 forwards, 96 backwards
>>> Branching T=179 (92.27%) F=15 (7.73%)
```
- Os
```
00000000000000101000110110011100
>>> Execution time: 93393 ns
>>> Instruction count: 889 (IPS=9518914)
>>> Jumps: 231 (25.98%) - 130 forwards, 101 backwards
>>> Branching T=158 (95.76%) F=7 (4.24%)
```
**gcd(1840564, 836620) = 167324**
The answer is all equal to `00000000000000101000110110011100`, which is `167324` in binary, and is all correct.