|
|
|
@ -507,6 +507,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) |
|
|
|
|
} |
|
|
|
|
case OPCODE_SYSTEM: |
|
|
|
|
{ |
|
|
|
|
uint32_t csr = instruction->immediate; |
|
|
|
|
switch(instruction->func3) |
|
|
|
|
{ |
|
|
|
|
case FUNC3_ECALL_EBREAK: |
|
|
|
@ -549,35 +550,39 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRW: |
|
|
|
|
// CSR atomic Read/Write
|
|
|
|
|
uint32_t csrrw_old_value = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] = cpu->regs.x[instruction->rs1]; |
|
|
|
|
uint32_t csrrw_old_value = 0; |
|
|
|
|
if(instruction->rd) |
|
|
|
|
csrrw_old_value = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, cpu->regs.x[instruction->rs1]); |
|
|
|
|
cpu->regs.x[instruction->rd] = csrrw_old_value; |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRS: |
|
|
|
|
// CSR atomic Read and Set bits
|
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] |= cpu->regs.x[instruction->rs1]; |
|
|
|
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs1]); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRC: |
|
|
|
|
// CSR atomic Read and Clear bits
|
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] &= (~cpu->regs.x[instruction->rs1]); |
|
|
|
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~cpu->regs.x[instruction->rs1])); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRWI: |
|
|
|
|
// CSR atomic Read/Write Immediate (immediate in rs1)
|
|
|
|
|
uint32_t csrrwi_old_value = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] = instruction->rs1; |
|
|
|
|
uint32_t csrrwi_old_value = 0; |
|
|
|
|
if(instruction->rd) |
|
|
|
|
csrrwi_old_value = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, instruction->rs1); |
|
|
|
|
cpu->regs.x[instruction->rd] = csrrwi_old_value; |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRSI: |
|
|
|
|
// CSR atomic Read and Set bits immediate
|
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] |= instruction->rs1; |
|
|
|
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] | instruction->rs1); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_CSRRCI: |
|
|
|
|
// CSR atomic Read and Clear bits Immediate (immediate in rs1)
|
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; |
|
|
|
|
cpu->csr[instruction->immediate] &= (~((uint32_t) instruction->rs1)); |
|
|
|
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr); |
|
|
|
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~((uint32_t) instruction->rs1))); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3); |
|
|
|
|