# Implement RISC-V Compressed Instruction Set on rv32emu
###### tags: `Computer Architecture`
# Some modifications for supporting the Compressed ext
1. Add a new variable named `insn_type` to distinguish the 16-bit and 32-bit instruction.
2. Modify the `unsigned char get_insn32(uint32_t, uint32_t*)` to return the type of instruction and then set the value to the pointer.
3. Modify the instruction offset, instead of always proceeding 4 bytes, it will depend on the type of instruction.
- 16-bits : 2 bytes
- 32-bits : 4 bytes
4. Rearrange the start of begin_signature.
# Verification through signature
We add a new function that the rv32emu can verify the result with the given signature.
## Example
The case which passes the test. That is, all signatures will be identical to the truth answer.
```shell
./emu-rv32i --elf work/rv32imc/C-ADDI.elf --signature work/rv32imc/C-ADDI.signature.output --output sig.txt
Unimplement Machine ecall!
00000001
00000002
0000000f
00000010
0000001f
00000002
00000003
00000010
00000011
00000020
00000000
00000001
0000000e
0000000f
0000001e
00080000
00080001
0008000e
0008000f
0008001e
00080001
00080002
0008000f
00080010
0008001f
00000000
00000000
00000000
work/rv32imc/C-ADDI.elf TEST PASSED
>>> Execution time: 116027 ns
>>> Instruction count: 136 (IPS=1172140)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
## Example2
The case which failed the test. It will output the answer you emulate and the answer shown at the right of the arrow.
```shell
./emu-rv32i --elf work/rv32imc/C-ADD.elf --signature work/rv32imc/C-ADD.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000000 -----> 00000001
00000001 -----> 00000002
ffffffff -----> 00000000
00007fff -----> 00008000
00008000 -----> 00008001
00000000 -----> ffffffff
00000001 -----> 00000000
ffffffff -----> fffffffe
00007fff -----> 00007ffe
00008000 -----> 00007fff
00000000 -----> 00007fff
00000001 -----> 00008000
ffffffff -----> 00007ffe
00007fff -----> 0000fffe
00008000 -----> 0000ffff
00000000 -----> 00008000
00000001 -----> 00008001
ffffffff -----> 00007fff
00007fff -----> 0000ffff
00008000 -----> 00010000
00000000
00000000
00000000
work/rv32imc/C-ADD.elf TEST FAILED
Number of failed signature : 20
>>> Execution time: 41813 ns
>>> Instruction count: 166 (IPS=3970057)
>>> Jumps: 2 (1.20%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
# Test suite
We produce the test data from [riscv-compliance](https://github.com/riscv/riscv-compliance) in the rv32imc extension.
## Opcode 0
#### C.ADDI4SPN
- [x] Imp
- [x] Test
- Encoding
- opcode : 0x00
- funct3 : 0x00
- Code:
```cpp
rd = (midpart & 0x7) + 8;
rs1 = 2;
imm = (midpart >> 4) & 0x1 |
(midpart >> 2) & 0x2 |
(midpart >> 7) & 0xe |
(midpart >> 1) & 0xf0;
imm = imm << 2;
imm = imm & 0x3ff;
val = reg[rs1] + imm;
```
- Test result:
```shell
./emu-rv32i --elf work/rv32imc/C-ADDI4SPN.elf --signature work/rv32imc/C-ADDI4SPN.signature.output --output sig.txt
00000004
00000008
0000000c
00000010
000003fc
00000000
00000000
00000000
work/rv32imc/C-ADDI4SPN.elf TEST PASSED
>>> Execution time: 14898 ns
>>> Instruction count: 64 (IPS=4295878)
>>> Jumps: 3 (4.69%) - 3 forwards, 0 backwards
>>> Branching T=2 (100.00%) F=0 (0.00%)
```
#### C.LW
- [x] Imp
- [x] Test
- Encoding
- opcode : 0x00
- funct3 : 0x01
- Code:
```cpp
rs1 = ((midpart >> 5) & 0x7) + 8;
rd = (midpart & 0x7) + 8;
imm = (midpart >> 4) & 0x1 |
(midpart >> 7) & 0xe |
(midpart << 1) & 0x10;
imm = (imm << 2) & 0x7f;
addr = reg[rs1] + imm;
uint32_t rval;
if (target_read_u32(&rval, addr)) {
raise_exception(pending_exception, pending_tval);
return;
}
val = (int32_t)rval;
```
- Test result:
```shell
./emu-rv32i --elf work/rv32imc/C-LW.elf --signature work/rv32imc/C-LW.signature.output --output sig.txt
11111111
22222222
33333333
44444444
55555555
00000000
00000000
00000000
work/rv32imc/C-LW.elf TEST PASSED
>>> Execution time: 15281 ns
>>> Instruction count: 73 (IPS=4777174)
>>> Jumps: 3 (4.11%) - 3 forwards, 0 backwards
>>> Branching T=2 (100.00%) F=0 (0.00%)
```
#### C.SW
- [x] Imp
- [x] Test
- Encoding
- opcode : 0x00
- funct3 : 0x01
- Code:
```cpp
rs1 = ((midpart >> 5) & 0x7) + 8;
rs2 = (midpart & 0x7) + 8;
imm = ((midpart >> 4) & 0x1) |
((midpart >> 7) & 0xe) |
((midpart << 1) & 0x10);
imm = (imm << 2) & 0x7f;
addr = reg[rs1] + imm;
val = reg[rs2];
rd = 0;
printf("addr: %08x\n", addr);
if (target_write_u32(addr, val)) {
raise_exception(pending_exception, pending_tval);
return;
}
```
- Test result:
## Opcode 1
#### C.NOP
- [x] Imp
- [x] Test
- Encoding
- opcode : 0x01
- funct3 : 0x00
- rs1'/rd' : 0x00
- Code:
- No operation.
- Test result:
```shell
./emu-rv32i --elf work/rv32imc/C-NOP.elf --signature work/rv32imc/C-NOP.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
work/rv32imc/C-NOP.elf TEST PASSED
>>> Execution time: 33541 ns
>>> Instruction count: 63 (IPS=1878298)
>>> Jumps: 2 (3.17%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.ADDi
- [x] Imp
- [x] Test
- Encoding
- opcode : 0x01
- funct3 : 0x00
- rs1`/rd` : Not zero
- Code:
```cpp
#ifdef DEBUG_EXTRA
dprintf(">>> C.ADDI\n");
#endif
rs1 = rd = ((midpart >> 5) & 0x1f);
imm = (midpart & 0x1f) | ((midpart >> 5) & 0x20);
val = reg[rs1] + imm;
```
- Test result:
```shell
./emu-rv32i --elf work/rv32imc/C-ADDI.elf --signature work/rv32imc/C-ADDI.signature.output --output sig.txt
Unimplement Machine ecall!
00000001
00000002
0000000f
00000010
0000001f
00000002
00000003
00000010
00000011
00000020
00000000
00000001
0000000e
0000000f
0000001e
00080000
00080001
0008000e
0008000f
0008001e
00080001
00080002
0008000f
00080010
0008001f
00000000
00000000
00000000
work/rv32imc/C-ADDI.elf TEST PASSED
>>> Execution time: 40375 ns
>>> Instruction count: 136 (IPS=3368421)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.JAL
- [x] Imp
- [x] Test
- Encoding (XLEN==32)
- Opcode : 0x01
- funct3 : 0x01
- Format : CJ
- Code
```cpp
rd = 0;
imm = (midpart & 0x400) |
((midpart << 3) & 0x200) |
(midpart & 0x180) |
((midpart << 2) & 0x40) |
(midpart & 0x20) |
((midpart << 4) & 0x10) |
((midpart >> 6) & 0x8) |
((midpart >> 1) & 0x7);
imm = (imm << 1) & 0xfffe;
reg[1] = pc + 2; /* Store the link to x1 register */
next_pc = (int32_t)(pc + imm);
if(next_pc > pc) forward_counter++;
else backward_counter++;
jump_counter++;
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-JAL.elf --signature work/rv32imc/C-JAL.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000000
00000000
00000000
work/rv32imc/C-JAL.elf TEST PASSED
>>> Execution time: 35857 ns
>>> Instruction count: 72 (IPS=2007976)
>>> Jumps: 7 (9.72%) - 7 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.ADDIW
- [x] Imp
- [ ] Test
- Encoding (XLEN==64/128)
- Opcode : 0x01
- funct3 : 0x01
- Format : CIW
- Code
```cpp
rs1 = rd = ((midpart >> 5) & 0x1f);
imm = (midpart >> (11 - 5)) |
(midpart & 0x1f);
val = reg[rs1] + imm;
```
#### C.LI
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x02
- Format : CI
- Code
```cpp
rs1 = rd = ((midpart >> 5) & 0x1f);
imm = ((midpart >> 5) & 0x20) | (midpart & 0x1f);
imm = imm << 26 >> 26;
val = imm;
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-LI.elf --signature work/rv32imc/C-LI.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000000
00000000
work/rv32imc/C-LI.elf TEST PASSED
>>> Execution time: 41022 ns
>>> Instruction count: 136 (IPS=3315294)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.ADDI16SP
- [x] Imp
- [x] Test
- Encoding(rd==2)
- Opcode : 0x01
- funct3 : 0x03
- Format : CI
- Code
```cpp
imm = ((midpart >> 4) & 0x1) |
((midpart << 1) & 0x2) |
((midpart >> 1) & 0x4) |
((midpart << 2) & 0x18)|
((midpart >> 5) & 0x20);
imm = (imm << 4 )<< (31 - 9) >> (31 - 9);
val = reg[rd] + imm;
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-ADDI16SP.elf --signature work/rv32imc/C-ADDI16SP.signature.output --output sig.txt
Unimplement Machine ecall!
00000010
00000030
00000070
00000260
00000060
00000000
00000000
00000000
work/rv32imc/C-ADDI16SP.elf TEST PASSED
>>> Execution time: 35052 ns
>>> Instruction count: 67 (IPS=1911445)
>>> Jumps: 2 (2.99%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.LUI
- [x] Imp
- [x] Test
- Encoding(rd!=0 | 2)
- Opcode : 0x01
- funct3 : 0x0
- Format : CI
- Code
```cpp
imm = (midpart & 0x1f) | ((midpart >> 5) & 0x20);
imm = (imm << 12);
if(imm == 0){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
if(rd != 0 && rd != 2){
val = (reg[rd] & ~0x0003f000) | imm;
val = val & 0xfffff000;
val = (int32_t) val << (31 - 17) >> (31 - 17);
}
else{
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-LUI.elf --signature work/rv32imc/C-LUI.signature.output --output sig.txt
Unimplement Machine ecall!
00001000
00002000
0000f000
0001f000
fffff000
00001000
00002000
0000f000
0001f000
fffff000
00001000
00002000
0000f000
0001f000
fffff000
00001000
00002000
0000f000
0001f000
fffff000
00001000
00002000
0000f000
0001f000
fffff000
00000000
00000000
00000000
work/rv32imc/C-LUI.elf TEST PASSED
>>> Execution time: 43830 ns
>>> Instruction count: 136 (IPS=3102897)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.SRLI
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CI
- Code
- XLEN = 32
```cpp
if((midpart >> 10 & 0x1)){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = (midpart & 0x1f) | (midpart >> 5 & 0x20);
if(imm == 0){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
val = reg[rs1];
```
- XLEN = 64
```cpp
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = (midpart & 0x1f) | (midpart >> 5 & 0x20);
if(imm == 0){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
val = reg[rs1];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-SRLI.elf --signature work/rv32imc/C-SRLI.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
7fffffff
3fffffff
0001ffff
0000ffff
00000001
0003ffff
0001ffff
0000000f
00000007
00000000
00040000
00020000
00000010
00000008
00000000
00000000
00000000
00000000
work/rv32imc/C-SRLI.elf TEST PASSED
>>> Execution time: 40809 ns
>>> Instruction count: 136 (IPS=3332598)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.SRLI64
- [x] Imp
- [ ] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CI
- Code
- XLEN = 128
```cpp
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = 64;
val = reg[rs1];
```
#### C.SRAI
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x05
- Format : CI
- Code
- XLEN = 32
```cpp
if((midpart >> 10 & 0x1)){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = (midpart & 0x1f) | (midpart >> 5 & 0x20);
if(imm == 0){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
val = reg[rs1];
```
- XLEN = 64
```cpp
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = (midpart & 0x1f) | (midpart >> 5 & 0x20);
if(imm == 0){
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
return;
}
val = reg[rs1];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-SRAI.elf --signature work/rv32imc/C-SRAI.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
0003ffff
0001ffff
0000000f
00000007
00000000
00040000
00020000
00000010
00000008
00000000
00000000
00000000
00000000
work/rv32imc/C-SRAI.elf TEST PASSED
>>> Execution time: 39850 ns
>>> Instruction count: 136 (IPS=3412797)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.SRAI64
- [x] Imp
- [ ] Test
- 128-bit version of `SRAI`
- Code
- XLEN = 128
```cpp
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = 64;
val = reg[rs1];
```
#### C.ANDI
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CI
- Code
```cpp
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
imm = (midpart & 0x1f) | ((midpart >> 5) & 0x20);
imm = imm << (31 - 5) >> (31 - 5);
val = reg[rs1];
val = val & imm;
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-ANDI.elf --signature work/rv32imc/C-ANDI.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000001
00000000
00000001
00000001
00000000
00000001
00000010
0000001f
ffffffe1
00000000
00000001
00000010
0000001f
0007ffe1
00000000
00000000
00000000
00000000
00080000
00000000
00000000
00000000
work/rv32imc/C-ANDI.elf TEST PASSED
>>> Execution time: 37497 ns
>>> Instruction count: 136 (IPS=3626956)
>>> Jumps: 2 (1.47%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.SUB
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] - reg[rs2];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-SUB.elf --signature work/rv32imc/C-SUB.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
ffffffff
00000000
fffffffe
00007ffe
00007fff
00000001
00000002
00000000
00008000
00008001
ffff8001
ffff8002
ffff8000
00000000
00000001
ffff8000
ffff8001
ffff7fff
ffffffff
00000000
00000000
00000000
00000000
work/rv32imc/C-SUB.elf TEST PASSED
>>> Execution time: 47664 ns
>>> Instruction count: 166 (IPS=3482712)
>>> Jumps: 2 (1.20%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.XOR
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] ^ reg[rs2];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-XOR.elf --signature work/rv32imc/C-XOR.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000001
00000000
fffffffe
00007ffe
00008001
ffffffff
fffffffe
00000000
ffff8000
ffff7fff
00007fff
00007ffe
ffff8000
00000000
0000ffff
00008000
00008001
ffff7fff
0000ffff
00000000
00000000
00000000
00000000
work/rv32imc/C-XOR.elf TEST PASSED
>>> Execution time: 38379 ns
>>> Instruction count: 166 (IPS=4325282)
>>> Jumps: 2 (1.20%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.OR
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] | reg[rs2];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-OR.elf --signature work/rv32imc/C-OR.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000001
00000001
ffffffff
00007fff
00008001
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
00007fff
00007fff
ffffffff
00007fff
0000ffff
00008000
00008001
ffffffff
0000ffff
00008000
00000000
00000000
00000000
work/rv32imc/C-OR.elf TEST PASSED
>>> Execution time: 41643 ns
>>> Instruction count: 166 (IPS=3986264)
>>> Jumps: 2 (1.20%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.AND
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] & reg[rs2];
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-AND.elf --signature work/rv32imc/C-AND.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000001
00000001
00000001
00000000
00000000
00000001
ffffffff
00007fff
00008000
00000000
00000001
00007fff
00007fff
00000000
00000000
00000000
00008000
00000000
00008000
00000000
00000000
00000000
work/rv32imc/C-AND.elf TEST PASSED
>>> Execution time: 40992 ns
>>> Instruction count: 166 (IPS=4049570)
>>> Jumps: 2 (1.20%) - 2 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.SUBW
- [x] Imp
- [ ] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code (Signed-ext for XLEN > 32)
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] - reg[rs2];
if(XLEN == 128){
val = (int32_t) (val << 96) >> 96;
}else if(XLEN == 64){
val = (int32_t) (val << 32) >> 32;
}else{
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
}
```
#### C.ADDW
- [x] Imp
- [ ] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x04
- Format : CR
- Code (Signed-ext for XLEN > 32)
```cpp
rs2 = (midpart & 0x7) + 8;
rs1 = rd = ((midpart >> 5) & 0x7) + 8;
val = reg[rd] + reg[rs2];
if(XLEN == 128){
val = (int32_t) (val << 96) >> 96;
}else if(XLEN == 64){
val = (int32_t) (val << 32) >> 32;
}else{
raise_exception(CAUSE_ILLEGAL_INSTRUCTION, insn);
}
```
#### C.J
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x05
- Format : CJ
- Code
```cpp
rd = 0;
imm = ((midpart >> 1) & 0x7) |
((midpart >> 6) & 0x8) |
((midpart << 4) & 0x10) |
((midpart) & 0x20) |
((midpart << 2) & 0x40) |
((midpart) & 0x180)|
((midpart << 3) & 0x200)|
((midpart) & 0x400);
imm = (imm << 1) << 20 >> 20;
next_pc = (int32_t)(pc + imm);
if(next_pc > pc) forward_counter++;
else backward_counter++;
jump_counter++;
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-J.elf --signature work/rv32imc/C-J.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000000
00000000
00000000
work/rv32imc/C-J.elf TEST PASSED
>>> Execution time: 34653 ns
>>> Instruction count: 72 (IPS=2077742)
>>> Jumps: 7 (9.72%) - 7 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.BEQZ
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x06
- Format : CB
- Code
```cpp
rs1 = ((midpart >> 5) & 0x7) + 8;
rd = 0;
if(reg[rs1] == 0){
imm = ((midpart >> 1) & 0x3) |
((midpart >> 6) & 0xc) |
((midpart << 4) & 0x10) |
((midpart << 2) & 0x60) |
((midpart >> 3) & 0x80);
imm = (imm << 1) << (31 - 8) >> (31 - 8);
next_pc = (int32_t)(pc + imm);
if(next_pc > pc) forward_counter++;
else backward_counter++;
jump_counter++;
}
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-BEQZ.elf --signature work/rv32imc/C-BEQZ.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
work/rv32imc/C-BEQZ.elf TEST PASSED
>>> Execution time: 35507 ns
>>> Instruction count: 77 (IPS=2168586)
>>> Jumps: 7 (9.09%) - 7 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
#### C.BNEZ
- [x] Imp
- [x] Test
- Encoding
- Opcode : 0x01
- funct3 : 0x07
- Format : CB
- Code
```cpp
rs1 = ((midpart >> 5) & 0x7) + 8;
rd = 0;
if(reg[rs1] != 0){
imm = ((midpart >> 1) & 0x3) |
((midpart >> 6) & 0xc) |
((midpart << 4) & 0x10) |
((midpart << 2) & 0x60) |
((midpart >> 3) & 0x80);
imm = (imm << 1) << (31 - 8) >> (31 - 8);
next_pc = (int32_t)(pc + imm);
if(next_pc > pc) forward_counter++;
else backward_counter++;
jump_counter++;
}
```
- Test result
```shell
./emu-rv32i --elf work/rv32imc/C-BNEZ.elf --signature work/rv32imc/C-BNEZ.signature.output --output sig.txt
Unimplement Machine ecall!
00000000
00000001
ffffffff
00007fff
00008000
00000000
00000000
00000000
work/rv32imc/C-BNEZ.elf TEST PASSED
>>> Execution time: 34728 ns
>>> Instruction count: 73 (IPS=2102050)
>>> Jumps: 6 (8.22%) - 6 forwards, 0 backwards
>>> Branching T=1 (50.00%) F=1 (50.00%)
```
## Opcode 2
- [x] C.SLLI(v)
```
```
- [ ] C.SLLI64
- [x] C.FLDSP
- [ ] C.LQSP
- [ ] C.LWSP(v)(it makes SWSP doesn't pass test so I delete it)
```
```
- [x] C.FLWSP
- [ ] C.LDSP
- [x] C.JR(v)
```
```
- [x] C.MV(v)
```
```
- [x] C.EBREAK(rewrite from rv32i?)
- [x] C.JALR(v)
```
```
- [x] C.ADD(v)
```
```
- [x] C.FSDSP
- [ ] C.SQSP
- [x] C.SWSP(v)(I record this without lwsp)
```
$ make C-SWSP.log
./emu-rv32i --elf work/rv32imc/C-SWSP.elf --signature work/rv32imc/C-SWSP.signature.output --output sig.txt
/*---------------------------------------*/
program end, result: 0000
done interp 57 int=0 mstatus=80 prv=3
00000000
00000001
ffffffff
00007fff
00008000
00000000
00000001
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
00007fff
ffffffff
00000000
00000000
00000000
work/rv32imc/C-SWSP.elf TEST PASSED
```
- [x] C.FSWSP
- [ ] C.SDSP
All for implement only, and unchecked part is not include in RV32, standing for non-testcase.