From 3888a0d65a5d9698b35704a6f5f6d578a7086430 Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Mon, 16 Dec 2024 22:16:31 +0000 Subject: [PATCH] Fix bugs in all base instructions and make RISCOF tests pass --- src/rve.cpp | 2 +- src/vm.cpp | 32 +++++++++++++++++++------------- test/rve/rve_isa.yaml | 1 + 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/rve.cpp b/src/rve.cpp index 7c7cc6c..2e614f4 100644 --- a/src/rve.cpp +++ b/src/rve.cpp @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) { } if (signature_filename.size() > 0) { - uint32_t signature_begin = std::get<0>(signature) + 4; + uint32_t signature_begin = std::get<0>(signature); uint32_t signature_end = std::get<1>(signature); std::vector mem = diff --git a/src/vm.cpp b/src/vm.cpp index 3eb470a..ad0d604 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -199,8 +199,8 @@ void VM::step() { } else if (funct3 == 0x02) { // SLT setreg(rd, (static_cast(registers[rs1]) < static_cast(registers[rs2])) - ? 0 - : 1); + ? 1 + : 0); } else if (funct3 == 0x03) { // SLTU setreg(rd, (registers[rs1] < registers[rs2]) ? 1 : 0); } else { @@ -294,7 +294,7 @@ void VM::step() { } } else if (funct3 == 0x05) { if (((imm >> 5) & 0x7f) == 0x20) { // SRAI - int32_t value = static_cast(imm & 0x1f); + int32_t value = registers[rs1]; int32_t shift_amount = imm & 0x1F; setreg(rd, value >> shift_amount); } else if (((imm >> 5) & 0x7f) == 0x0) { // SRLI @@ -307,8 +307,8 @@ void VM::step() { } else if (funct3 == 0x02) { // SLTI setreg(rd, (static_cast(registers[rs1]) < static_cast(imm)) - ? 0 - : 1); + ? 1 + : 0); } else if (funct3 == 0x03) { // SLTIU setreg(rd, (registers[rs1] < static_cast(imm)) ? 1 : 0); } else { @@ -353,10 +353,10 @@ void VM::step() { imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate if (funct3 == 0x00) { // LB uint32_t addr = registers[rs1] + imm; - setreg(rd, read_memory_byte(addr)); + setreg(rd, sign_extend(read_memory_byte(addr), 8)); } else if (funct3 == 0x01) { // LH uint32_t addr = registers[rs1] + imm; - setreg(rd, read_memory_half_word(addr)); + setreg(rd, sign_extend(read_memory_half_word(addr), 16)); } else if (funct3 == 0x2) { // LW uint32_t addr = registers[rs1] + imm; setreg(rd, read_memory_word(addr)); @@ -400,8 +400,9 @@ void VM::step() { pc += offset - 4; break; } - case 0x67: { // JALR - int32_t offset = (instr >> 20); // Sign-extended 12-bit immediate + case 0x67: { // JALR + int32_t offset = + sign_extend(instr >> 20, 12); // Sign-extended 12-bit immediate uint32_t target = (registers[rs1] + offset) & ~1; // Target address (LSB cleared) @@ -423,10 +424,15 @@ void VM::step() { // the current PC break; } - case 0x73: { // EBREAK - pc -= 4; - throw EbreakException(); - break; + case 0x73: { + imm = sign_extend(instr >> 20, 12); // Extract 12-bit immediate + if (funct3 == 0x0 && imm == 0x1) { // EBREAK + pc -= 4; + throw EbreakException(); + break; + } else { + throw std::runtime_error("Unknown opcode"); + } } default: throw std::runtime_error("Unknown opcode"); diff --git a/test/rve/rve_isa.yaml b/test/rve/rve_isa.yaml index 9f6e61e..0ab81d5 100644 --- a/test/rve/rve_isa.yaml +++ b/test/rve/rve_isa.yaml @@ -4,6 +4,7 @@ hart0: physical_addr_sz: 32 User_Spec_Version: '2.3' supported_xlen: [32] + hw_data_misaligned_support: false misa: # reset-val encodes the CPU capabilities in a special register, # as specified in https://five-embeddev.com/riscv-priv-isa-manual/Priv-v1.12/machine.html