diff --git a/src/cpu/instruction.h b/src/cpu/instruction.h index bb171b4..479edb9 100644 --- a/src/cpu/instruction.h +++ b/src/cpu/instruction.h @@ -60,7 +60,16 @@ #define FUNC3_OR 0x7 #define FUNC3_AND 0x8 +/* OPCODE_SYSTEM sub functions (func3 + imm) */ +#define FUNC3_ECALL_EBREAK 0x0 #define IMM_ECALL 0x0 #define IMM_EBREAK 0x1 +/* RISC-V RV32 ZICSR Extension */ +#define FUNC3_CSRRW 0x1 +#define FUNC3_CSRRS 0x2 +#define FUNC3_CSRRC 0x3 +#define FUNC3_CSRRWI 0x5 +#define FUNC3_CSRRSI 0x6 +#define FUNC3_CSRRCI 0x7 #endif diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index 090b1ea..ab24826 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -417,19 +417,47 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) } case OPCODE_SYSTEM: { - switch(instruction->immediate) + switch(instruction->func3) { - case IMM_ECALL: - fprintf(stderr, "ECALL: a7(sbi ext id) = %d, a6(sbi funct id) = %d\n", cpu->regs.a7, cpu->regs.a6); + case FUNC3_ECALL_EBREAK: + switch(instruction->immediate) + { + case IMM_ECALL: + fprintf(stderr, "ECALL: a7(sbi ext id) = %d, a6(sbi funct id) = %d\n", cpu->regs.a7, cpu->regs.a6); + break; + case IMM_EBREAK: + fprintf(stderr, "EBREAK\n"); + break; + default: + fprintf(stderr, "FATAL: Unknown IMM for ECALL/EBREAK instruction while executing (IMM=0x%x)\n", instruction->immediate); + exit(EXIT_FAILURE); + break; + } + break; + case FUNC3_CSRRW: + fprintf(stderr, "CSRRW\n"); + break; + case FUNC3_CSRRS: + fprintf(stderr, "CSRRS\n"); + break; + case FUNC3_CSRRC: + fprintf(stderr, "CSRRC\n"); + break; + case FUNC3_CSRRWI: + fprintf(stderr, "CSRRWI\n"); + break; + case FUNC3_CSRRSI: + fprintf(stderr, "CSRRSI\n"); break; - case IMM_EBREAK: - fprintf(stderr, "EBREAK\n"); + case FUNC3_CSRRCI: + fprintf(stderr, "CSRRCI\n"); break; default: - fprintf(stderr, "FATAL: Unknown SYSTEM instruction while executing (IMM=0x%x)\n", instruction->immediate); + fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3); exit(EXIT_FAILURE); break; } + break; } default: @@ -456,6 +484,7 @@ void cpu_loop(rv32_cpu_t* cpu) instruction_t instruction; cpu_decode(raw_instruction, &instruction); + printf("0x%x: ", cpu->pc); cpu_print_instruction(&instruction); // Execute @@ -730,16 +759,42 @@ static void cpu_print_instruction(instruction_t* instruction) } case OPCODE_SYSTEM: { - switch(instruction->immediate) + switch(instruction->func3) { - case IMM_ECALL: - printf("ecall\n"); + case FUNC3_ECALL_EBREAK: + switch(instruction->immediate) + { + case IMM_ECALL: + printf("ecall\n"); + break; + case IMM_EBREAK: + printf("ebreak\n"); + break; + default: + fprintf(stderr, "Warning: Unknown IMM for ECALL/EBREAK instruction (IMM=0x%x)\n", instruction->immediate); + break; + } + break; + case FUNC3_CSRRW: + printf("csrrw csr[0x%x], x%u, x%u\n", instruction->immediate, instruction->rd, instruction->rs1); + break; + case FUNC3_CSRRS: + printf("csrrs csr[0x%x], x%u, x%u\n", instruction->immediate, instruction->rd, instruction->rs1); + break; + case FUNC3_CSRRC: + printf("csrrc csr[0x%x], x%u, x%u\n", instruction->immediate, instruction->rd, instruction->rs1); + break; + case FUNC3_CSRRWI: + printf("csrrwi csr[0x%x], x%u, 0x%x\n", instruction->immediate, instruction->rd, instruction->rs1); + break; + case FUNC3_CSRRSI: + printf("csrrsi csr[0x%x], x%u, 0x%x\n", instruction->immediate, instruction->rd, instruction->rs1); break; - case IMM_EBREAK: - printf("ebreak\n"); + case FUNC3_CSRRCI: + printf("csrrci csr[0x%x], x%u, 0x%x\n", instruction->immediate, instruction->rd, instruction->rs1); break; default: - fprintf(stderr, "Warning: Unknown SYSTEM instruction (IMM=0x%x)\n", instruction->immediate); + fprintf(stderr, "Warning: Unknown func3 0x%x for SYSTEM instruction\n", instruction->func3); break; } break;