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